rubyzip 0.9.1 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +354 -0
  3. data/Rakefile +15 -104
  4. data/TODO +0 -1
  5. data/lib/zip/central_directory.rb +212 -0
  6. data/lib/zip/compressor.rb +9 -0
  7. data/lib/zip/constants.rb +115 -0
  8. data/lib/zip/crypto/decrypted_io.rb +40 -0
  9. data/lib/zip/crypto/encryption.rb +11 -0
  10. data/lib/zip/crypto/null_encryption.rb +43 -0
  11. data/lib/zip/crypto/traditional_encryption.rb +99 -0
  12. data/lib/zip/decompressor.rb +31 -0
  13. data/lib/zip/deflater.rb +34 -0
  14. data/lib/zip/dos_time.rb +53 -0
  15. data/lib/zip/entry.rb +719 -0
  16. data/lib/zip/entry_set.rb +88 -0
  17. data/lib/zip/errors.rb +19 -0
  18. data/lib/zip/extra_field/generic.rb +44 -0
  19. data/lib/zip/extra_field/ntfs.rb +94 -0
  20. data/lib/zip/extra_field/old_unix.rb +46 -0
  21. data/lib/zip/extra_field/universal_time.rb +77 -0
  22. data/lib/zip/extra_field/unix.rb +39 -0
  23. data/lib/zip/extra_field/zip64.rb +70 -0
  24. data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
  25. data/lib/zip/extra_field.rb +103 -0
  26. data/lib/zip/file.rb +468 -0
  27. data/lib/zip/filesystem.rb +643 -0
  28. data/lib/zip/inflater.rb +54 -0
  29. data/lib/zip/input_stream.rb +180 -0
  30. data/lib/zip/ioextras/abstract_input_stream.rb +122 -0
  31. data/lib/zip/ioextras/abstract_output_stream.rb +43 -0
  32. data/lib/zip/ioextras.rb +21 -140
  33. data/lib/zip/null_compressor.rb +15 -0
  34. data/lib/zip/null_decompressor.rb +19 -0
  35. data/lib/zip/null_input_stream.rb +10 -0
  36. data/lib/zip/output_stream.rb +198 -0
  37. data/lib/zip/pass_thru_compressor.rb +23 -0
  38. data/lib/zip/pass_thru_decompressor.rb +31 -0
  39. data/lib/zip/streamable_directory.rb +15 -0
  40. data/lib/zip/streamable_stream.rb +52 -0
  41. data/lib/zip/version.rb +3 -0
  42. data/lib/zip.rb +72 -0
  43. data/samples/example.rb +44 -32
  44. data/samples/example_filesystem.rb +16 -19
  45. data/samples/example_recursive.rb +54 -0
  46. data/samples/gtk_ruby_zip.rb +84 -0
  47. data/samples/qtzip.rb +25 -34
  48. data/samples/write_simple.rb +10 -13
  49. data/samples/zipfind.rb +38 -45
  50. metadata +182 -91
  51. data/ChangeLog +0 -1504
  52. data/NEWS +0 -144
  53. data/README +0 -72
  54. data/install.rb +0 -22
  55. data/lib/download_quizzes.rb +0 -119
  56. data/lib/quiz1/t/solutions/Bill Guindon/solitaire.rb +0 -205
  57. data/lib/quiz1/t/solutions/Carlos/solitaire.rb +0 -111
  58. data/lib/quiz1/t/solutions/Dennis Ranke/solitaire.rb +0 -111
  59. data/lib/quiz1/t/solutions/Florian Gross/solitaire.rb +0 -301
  60. data/lib/quiz1/t/solutions/Glen M. Lewis/solitaire.rb +0 -268
  61. data/lib/quiz1/t/solutions/James Edward Gray II/solitaire.rb +0 -132
  62. data/lib/quiz1/t/solutions/Jamis Buck/bin/main.rb +0 -13
  63. data/lib/quiz1/t/solutions/Jamis Buck/lib/cipher.rb +0 -230
  64. data/lib/quiz1/t/solutions/Jamis Buck/lib/cli.rb +0 -24
  65. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_deck.rb +0 -30
  66. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_key-stream.rb +0 -19
  67. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_keying-algorithms.rb +0 -31
  68. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_solitaire-cipher.rb +0 -66
  69. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_unkeyed-algorithm.rb +0 -17
  70. data/lib/quiz1/t/solutions/Jamis Buck/test/tests.rb +0 -2
  71. data/lib/quiz1/t/solutions/Jim Menard/solitaire_cypher.rb +0 -204
  72. data/lib/quiz1/t/solutions/Jim Menard/test.rb +0 -47
  73. data/lib/quiz1/t/solutions/Moses Hohman/cipher.rb +0 -97
  74. data/lib/quiz1/t/solutions/Moses Hohman/deck.rb +0 -140
  75. data/lib/quiz1/t/solutions/Moses Hohman/solitaire.rb +0 -14
  76. data/lib/quiz1/t/solutions/Moses Hohman/test_cipher.rb +0 -68
  77. data/lib/quiz1/t/solutions/Moses Hohman/test_deck.rb +0 -146
  78. data/lib/quiz1/t/solutions/Moses Hohman/test_util.rb +0 -38
  79. data/lib/quiz1/t/solutions/Moses Hohman/testsuite.rb +0 -5
  80. data/lib/quiz1/t/solutions/Moses Hohman/util.rb +0 -27
  81. data/lib/quiz1/t/solutions/Niklas Frykholm/solitaire.rb +0 -151
  82. data/lib/quiz1/t/solutions/Thomas Leitner/solitaire.rb +0 -198
  83. data/lib/zip/stdrubyext.rb +0 -111
  84. data/lib/zip/tempfile_bugfixed.rb +0 -195
  85. data/lib/zip/zip.rb +0 -1847
  86. data/lib/zip/zipfilesystem.rb +0 -609
  87. data/lib/zip/ziprequire.rb +0 -90
  88. data/samples/gtkRubyzip.rb +0 -86
  89. data/test/alltests.rb +0 -9
  90. data/test/data/file1.txt +0 -46
  91. data/test/data/file1.txt.deflatedData +0 -0
  92. data/test/data/file2.txt +0 -1504
  93. data/test/data/notzippedruby.rb +0 -7
  94. data/test/data/rubycode.zip +0 -0
  95. data/test/data/rubycode2.zip +0 -0
  96. data/test/data/testDirectory.bin +0 -0
  97. data/test/data/zipWithDirs.zip +0 -0
  98. data/test/gentestfiles.rb +0 -157
  99. data/test/ioextrastest.rb +0 -208
  100. data/test/stdrubyexttest.rb +0 -52
  101. data/test/zipfilesystemtest.rb +0 -831
  102. data/test/ziprequiretest.rb +0 -43
  103. data/test/ziptest.rb +0 -1599
data/test/ziptest.rb DELETED
@@ -1,1599 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $VERBOSE = true
4
-
5
- $: << "../lib"
6
-
7
- require 'test/unit'
8
- require 'zip/zip'
9
- require 'gentestfiles'
10
-
11
- include Zip
12
-
13
-
14
- class ZipEntryTest < Test::Unit::TestCase
15
- TEST_ZIPFILE = "someZipFile.zip"
16
- TEST_COMMENT = "a comment"
17
- TEST_COMPRESSED_SIZE = 1234
18
- TEST_CRC = 325324
19
- TEST_EXTRA = "Some data here"
20
- TEST_COMPRESSIONMETHOD = ZipEntry::DEFLATED
21
- TEST_NAME = "entry name"
22
- TEST_SIZE = 8432
23
- TEST_ISDIRECTORY = false
24
-
25
- def test_constructorAndGetters
26
- entry = ZipEntry.new(TEST_ZIPFILE,
27
- TEST_NAME,
28
- TEST_COMMENT,
29
- TEST_EXTRA,
30
- TEST_COMPRESSED_SIZE,
31
- TEST_CRC,
32
- TEST_COMPRESSIONMETHOD,
33
- TEST_SIZE)
34
-
35
- assert_equal(TEST_COMMENT, entry.comment)
36
- assert_equal(TEST_COMPRESSED_SIZE, entry.compressed_size)
37
- assert_equal(TEST_CRC, entry.crc)
38
- assert_instance_of(Zip::ZipExtraField, entry.extra)
39
- assert_equal(TEST_COMPRESSIONMETHOD, entry.compression_method)
40
- assert_equal(TEST_NAME, entry.name)
41
- assert_equal(TEST_SIZE, entry.size)
42
- assert_equal(TEST_ISDIRECTORY, entry.is_directory)
43
- end
44
-
45
- def test_is_directoryAndIsFile
46
- assert(ZipEntry.new(TEST_ZIPFILE, "hello").file?)
47
- assert(! ZipEntry.new(TEST_ZIPFILE, "hello").directory?)
48
-
49
- assert(ZipEntry.new(TEST_ZIPFILE, "dir/hello").file?)
50
- assert(! ZipEntry.new(TEST_ZIPFILE, "dir/hello").directory?)
51
-
52
- assert(ZipEntry.new(TEST_ZIPFILE, "hello/").directory?)
53
- assert(! ZipEntry.new(TEST_ZIPFILE, "hello/").file?)
54
-
55
- assert(ZipEntry.new(TEST_ZIPFILE, "dir/hello/").directory?)
56
- assert(! ZipEntry.new(TEST_ZIPFILE, "dir/hello/").file?)
57
- end
58
-
59
- def test_equality
60
- entry1 = ZipEntry.new("file.zip", "name", "isNotCompared",
61
- "something extra", 123, 1234,
62
- ZipEntry::DEFLATED, 10000)
63
- entry2 = ZipEntry.new("file.zip", "name", "isNotComparedXXX",
64
- "something extra", 123, 1234,
65
- ZipEntry::DEFLATED, 10000)
66
- entry3 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
67
- "something extra", 123, 1234,
68
- ZipEntry::DEFLATED, 10000)
69
- entry4 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
70
- "something extraXX", 123, 1234,
71
- ZipEntry::DEFLATED, 10000)
72
- entry5 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
73
- "something extraXX", 12, 1234,
74
- ZipEntry::DEFLATED, 10000)
75
- entry6 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
76
- "something extraXX", 12, 123,
77
- ZipEntry::DEFLATED, 10000)
78
- entry7 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
79
- "something extraXX", 12, 123,
80
- ZipEntry::STORED, 10000)
81
- entry8 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
82
- "something extraXX", 12, 123,
83
- ZipEntry::STORED, 100000)
84
-
85
- assert_equal(entry1, entry1)
86
- assert_equal(entry1, entry2)
87
-
88
- assert(entry2 != entry3)
89
- assert(entry3 != entry4)
90
- assert(entry4 != entry5)
91
- assert(entry5 != entry6)
92
- assert(entry6 != entry7)
93
- assert(entry7 != entry8)
94
-
95
- assert(entry7 != "hello")
96
- assert(entry7 != 12)
97
- end
98
-
99
- def test_compare
100
- assert_equal(0, (ZipEntry.new("zf.zip", "a") <=> ZipEntry.new("zf.zip", "a")))
101
- assert_equal(1, (ZipEntry.new("zf.zip", "b") <=> ZipEntry.new("zf.zip", "a")))
102
- assert_equal(-1, (ZipEntry.new("zf.zip", "a") <=> ZipEntry.new("zf.zip", "b")))
103
-
104
- entries = [
105
- ZipEntry.new("zf.zip", "5"),
106
- ZipEntry.new("zf.zip", "1"),
107
- ZipEntry.new("zf.zip", "3"),
108
- ZipEntry.new("zf.zip", "4"),
109
- ZipEntry.new("zf.zip", "0"),
110
- ZipEntry.new("zf.zip", "2")
111
- ]
112
-
113
- entries.sort!
114
- assert_equal("0", entries[0].to_s)
115
- assert_equal("1", entries[1].to_s)
116
- assert_equal("2", entries[2].to_s)
117
- assert_equal("3", entries[3].to_s)
118
- assert_equal("4", entries[4].to_s)
119
- assert_equal("5", entries[5].to_s)
120
- end
121
-
122
- def test_parentAsString
123
- entry1 = ZipEntry.new("zf.zip", "aa")
124
- entry2 = ZipEntry.new("zf.zip", "aa/")
125
- entry3 = ZipEntry.new("zf.zip", "aa/bb")
126
- entry4 = ZipEntry.new("zf.zip", "aa/bb/")
127
- entry5 = ZipEntry.new("zf.zip", "aa/bb/cc")
128
- entry6 = ZipEntry.new("zf.zip", "aa/bb/cc/")
129
-
130
- assert_equal(nil, entry1.parent_as_string)
131
- assert_equal(nil, entry2.parent_as_string)
132
- assert_equal("aa/", entry3.parent_as_string)
133
- assert_equal("aa/", entry4.parent_as_string)
134
- assert_equal("aa/bb/", entry5.parent_as_string)
135
- assert_equal("aa/bb/", entry6.parent_as_string)
136
- end
137
-
138
- def test_entry_name_cannot_start_with_slash
139
- assert_raise(ZipEntryNameError) { ZipEntry.new("zf.zip", "/hej/der") }
140
- end
141
- end
142
-
143
- module IOizeString
144
- attr_reader :tell
145
-
146
- def read(count = nil)
147
- @tell ||= 0
148
- count = size unless count
149
- retVal = slice(@tell, count)
150
- @tell += count
151
- return retVal
152
- end
153
-
154
- def seek(index, offset)
155
- @tell ||= 0
156
- case offset
157
- when IO::SEEK_END
158
- newPos = size + index
159
- when IO::SEEK_SET
160
- newPos = index
161
- when IO::SEEK_CUR
162
- newPos = @tell + index
163
- else
164
- raise "Error in test method IOizeString::seek"
165
- end
166
- if (newPos < 0 || newPos >= size)
167
- raise Errno::EINVAL
168
- else
169
- @tell=newPos
170
- end
171
- end
172
-
173
- def reset
174
- @tell = 0
175
- end
176
- end
177
-
178
- class ZipLocalEntryTest < Test::Unit::TestCase
179
- def test_read_local_entryHeaderOfFirstTestZipEntry
180
- File.open(TestZipFile::TEST_ZIP3.zip_name, "rb") {
181
- |file|
182
- entry = ZipEntry.read_local_entry(file)
183
-
184
- assert_equal("", entry.comment)
185
- # Differs from windows and unix because of CR LF
186
- # assert_equal(480, entry.compressed_size)
187
- # assert_equal(0x2a27930f, entry.crc)
188
- # extra field is 21 bytes long
189
- # probably contains some unix attrutes or something
190
- # disabled: assert_equal(nil, entry.extra)
191
- assert_equal(ZipEntry::DEFLATED, entry.compression_method)
192
- assert_equal(TestZipFile::TEST_ZIP3.entry_names[0], entry.name)
193
- assert_equal(File.size(TestZipFile::TEST_ZIP3.entry_names[0]), entry.size)
194
- assert(! entry.is_directory)
195
- }
196
- end
197
-
198
- def test_readDateTime
199
- File.open("data/rubycode.zip", "rb") {
200
- |file|
201
- entry = ZipEntry.read_local_entry(file)
202
- assert_equal("zippedruby1.rb", entry.name)
203
- assert_equal(Time.at(1019261638), entry.time)
204
- }
205
- end
206
-
207
- def test_read_local_entryFromNonZipFile
208
- File.open("data/file2.txt") {
209
- |file|
210
- assert_equal(nil, ZipEntry.read_local_entry(file))
211
- }
212
- end
213
-
214
- def test_read_local_entryFromTruncatedZipFile
215
- zipFragment=""
216
- File.open(TestZipFile::TEST_ZIP2.zip_name) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
217
- zipFragment.extend(IOizeString).reset
218
- entry = ZipEntry.new
219
- entry.read_local_entry(zipFragment)
220
- fail "ZipError expected"
221
- rescue ZipError
222
- end
223
-
224
- def test_writeEntry
225
- entry = ZipEntry.new("file.zip", "entryName", "my little comment",
226
- "thisIsSomeExtraInformation", 100, 987654,
227
- ZipEntry::DEFLATED, 400)
228
- write_to_file("localEntryHeader.bin", "centralEntryHeader.bin", entry)
229
- entryReadLocal, entryReadCentral = read_from_file("localEntryHeader.bin", "centralEntryHeader.bin")
230
- compare_local_entry_headers(entry, entryReadLocal)
231
- compare_c_dir_entry_headers(entry, entryReadCentral)
232
- end
233
-
234
- private
235
- def compare_local_entry_headers(entry1, entry2)
236
- assert_equal(entry1.compressed_size , entry2.compressed_size)
237
- assert_equal(entry1.crc , entry2.crc)
238
- assert_equal(entry1.extra , entry2.extra)
239
- assert_equal(entry1.compression_method, entry2.compression_method)
240
- assert_equal(entry1.name , entry2.name)
241
- assert_equal(entry1.size , entry2.size)
242
- assert_equal(entry1.localHeaderOffset, entry2.localHeaderOffset)
243
- end
244
-
245
- def compare_c_dir_entry_headers(entry1, entry2)
246
- compare_local_entry_headers(entry1, entry2)
247
- assert_equal(entry1.comment, entry2.comment)
248
- end
249
-
250
- def write_to_file(localFileName, centralFileName, entry)
251
- File.open(localFileName, "wb") { |f| entry.write_local_entry(f) }
252
- File.open(centralFileName, "wb") { |f| entry.write_c_dir_entry(f) }
253
- end
254
-
255
- def read_from_file(localFileName, centralFileName)
256
- localEntry = nil
257
- cdirEntry = nil
258
- File.open(localFileName, "rb") { |f| localEntry = ZipEntry.read_local_entry(f) }
259
- File.open(centralFileName, "rb") { |f| cdirEntry = ZipEntry.read_c_dir_entry(f) }
260
- return [localEntry, cdirEntry]
261
- end
262
- end
263
-
264
-
265
- module DecompressorTests
266
- # expects @refText, @refLines and @decompressor
267
-
268
- TEST_FILE="data/file1.txt"
269
-
270
- def setup
271
- @refText=""
272
- File.open(TEST_FILE) { |f| @refText = f.read }
273
- @refLines = @refText.split($/)
274
- end
275
-
276
- def test_readEverything
277
- assert_equal(@refText, @decompressor.sysread)
278
- end
279
-
280
- def test_readInChunks
281
- chunkSize = 5
282
- while (decompressedChunk = @decompressor.sysread(chunkSize))
283
- assert_equal(@refText.slice!(0, chunkSize), decompressedChunk)
284
- end
285
- assert_equal(0, @refText.size)
286
- end
287
-
288
- def test_mixingReadsAndProduceInput
289
- # Just some preconditions to make sure we have enough data for this test
290
- assert(@refText.length > 1000)
291
- assert(@refLines.length > 40)
292
-
293
-
294
- assert_equal(@refText[0...100], @decompressor.sysread(100))
295
-
296
- assert(! @decompressor.input_finished?)
297
- buf = @decompressor.produce_input
298
- assert_equal(@refText[100...(100+buf.length)], buf)
299
- end
300
- end
301
-
302
- class InflaterTest < Test::Unit::TestCase
303
- include DecompressorTests
304
-
305
- def setup
306
- super
307
- @file = File.new("data/file1.txt.deflatedData", "rb")
308
- @decompressor = Inflater.new(@file)
309
- end
310
-
311
- def teardown
312
- @file.close
313
- end
314
- end
315
-
316
-
317
- class PassThruDecompressorTest < Test::Unit::TestCase
318
- include DecompressorTests
319
- def setup
320
- super
321
- @file = File.new(TEST_FILE)
322
- @decompressor = PassThruDecompressor.new(@file, File.size(TEST_FILE))
323
- end
324
-
325
- def teardown
326
- @file.close
327
- end
328
- end
329
-
330
-
331
- module AssertEntry
332
- def assert_next_entry(filename, zis)
333
- assert_entry(filename, zis, zis.get_next_entry.name)
334
- end
335
-
336
- def assert_entry(filename, zis, entryName)
337
- assert_equal(filename, entryName)
338
- assert_entryContentsForStream(filename, zis, entryName)
339
- end
340
-
341
- def assert_entryContentsForStream(filename, zis, entryName)
342
- File.open(filename, "rb") {
343
- |file|
344
- expected = file.read
345
- actual = zis.read
346
- if (expected != actual)
347
- if ((expected && actual) && (expected.length > 400 || actual.length > 400))
348
- zipEntryFilename=entryName+".zipEntry"
349
- File.open(zipEntryFilename, "wb") { |file| file << actual }
350
- fail("File '#{filename}' is different from '#{zipEntryFilename}'")
351
- else
352
- assert_equal(expected, actual)
353
- end
354
- end
355
- }
356
- end
357
-
358
- def AssertEntry.assert_contents(filename, aString)
359
- fileContents = ""
360
- File.open(filename, "rb") { |f| fileContents = f.read }
361
- if (fileContents != aString)
362
- if (fileContents.length > 400 || aString.length > 400)
363
- stringFile = filename + ".other"
364
- File.open(stringFile, "wb") { |f| f << aString }
365
- fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
366
- else
367
- assert_equal(fileContents, aString)
368
- end
369
- end
370
- end
371
-
372
- def assert_stream_contents(zis, testZipFile)
373
- assert(zis != nil)
374
- testZipFile.entry_names.each {
375
- |entryName|
376
- assert_next_entry(entryName, zis)
377
- }
378
- assert_equal(nil, zis.get_next_entry)
379
- end
380
-
381
- def assert_test_zip_contents(testZipFile)
382
- ZipInputStream.open(testZipFile.zip_name) {
383
- |zis|
384
- assert_stream_contents(zis, testZipFile)
385
- }
386
- end
387
-
388
- def assert_entryContents(zipFile, entryName, filename = entryName.to_s)
389
- zis = zipFile.get_input_stream(entryName)
390
- assert_entryContentsForStream(filename, zis, entryName)
391
- ensure
392
- zis.close if zis
393
- end
394
- end
395
-
396
-
397
-
398
- class ZipInputStreamTest < Test::Unit::TestCase
399
- include AssertEntry
400
-
401
- def test_new
402
- zis = ZipInputStream.new(TestZipFile::TEST_ZIP2.zip_name)
403
- assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
404
- assert_equal(true, zis.eof?)
405
- zis.close
406
- end
407
-
408
- def test_openWithBlock
409
- ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
410
- |zis|
411
- assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
412
- assert_equal(true, zis.eof?)
413
- }
414
- end
415
-
416
- def test_openWithoutBlock
417
- zis = ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name)
418
- assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
419
- end
420
-
421
- def test_incompleteReads
422
- ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
423
- |zis|
424
- entry = zis.get_next_entry # longAscii.txt
425
- assert_equal(false, zis.eof?)
426
- assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
427
- assert zis.gets.length > 0
428
- assert_equal(false, zis.eof?)
429
- entry = zis.get_next_entry # empty.txt
430
- assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
431
- assert_equal(0, entry.size)
432
- assert_equal(nil, zis.gets)
433
- assert_equal(true, zis.eof?)
434
- entry = zis.get_next_entry # empty_chmod640.txt
435
- assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
436
- assert_equal(0, entry.size)
437
- assert_equal(nil, zis.gets)
438
- assert_equal(true, zis.eof?)
439
- entry = zis.get_next_entry # short.txt
440
- assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
441
- assert zis.gets.length > 0
442
- entry = zis.get_next_entry # longBinary.bin
443
- assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
444
- assert zis.gets.length > 0
445
- }
446
- end
447
-
448
- def test_rewind
449
- ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
450
- |zis|
451
- e = zis.get_next_entry
452
- assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], e.name)
453
-
454
- # Do a little reading
455
- buf = ""
456
- buf << zis.read(100)
457
- buf << (zis.gets || "")
458
- buf << (zis.gets || "")
459
- assert_equal(false, zis.eof?)
460
-
461
- zis.rewind
462
-
463
- buf2 = ""
464
- buf2 << zis.read(100)
465
- buf2 << (zis.gets || "")
466
- buf2 << (zis.gets || "")
467
-
468
- assert_equal(buf, buf2)
469
-
470
- zis.rewind
471
- assert_equal(false, zis.eof?)
472
-
473
- assert_entry(e.name, zis, e.name)
474
- }
475
- end
476
-
477
- def test_mix_read_and_gets
478
- ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
479
- |zis|
480
- e = zis.get_next_entry
481
- assert_equal("#!/usr/bin/env ruby", zis.gets.chomp)
482
- assert_equal(false, zis.eof?)
483
- assert_equal("", zis.gets.chomp)
484
- assert_equal(false, zis.eof?)
485
- assert_equal("$VERBOSE =", zis.read(10))
486
- assert_equal(false, zis.eof?)
487
- }
488
- end
489
-
490
- end
491
-
492
-
493
- module CrcTest
494
-
495
- class TestOutputStream
496
- include IOExtras::AbstractOutputStream
497
-
498
- attr_accessor :buffer
499
-
500
- def initialize
501
- @buffer = ""
502
- end
503
-
504
- def << (data)
505
- @buffer << data
506
- self
507
- end
508
- end
509
-
510
- def run_crc_test(compressorClass)
511
- str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
512
- fakeOut = TestOutputStream.new
513
-
514
- deflater = compressorClass.new(fakeOut)
515
- deflater << str
516
- assert_equal(0x919920fc, deflater.crc)
517
- end
518
- end
519
-
520
-
521
-
522
- class PassThruCompressorTest < Test::Unit::TestCase
523
- include CrcTest
524
-
525
- def test_size
526
- File.open("dummy.txt", "wb") {
527
- |file|
528
- compressor = PassThruCompressor.new(file)
529
-
530
- assert_equal(0, compressor.size)
531
-
532
- t1 = "hello world"
533
- t2 = ""
534
- t3 = "bingo"
535
-
536
- compressor << t1
537
- assert_equal(compressor.size, t1.size)
538
-
539
- compressor << t2
540
- assert_equal(compressor.size, t1.size + t2.size)
541
-
542
- compressor << t3
543
- assert_equal(compressor.size, t1.size + t2.size + t3.size)
544
- }
545
- end
546
-
547
- def test_crc
548
- run_crc_test(PassThruCompressor)
549
- end
550
- end
551
-
552
- class DeflaterTest < Test::Unit::TestCase
553
- include CrcTest
554
-
555
- def test_outputOperator
556
- txt = load_file("data/file2.txt")
557
- deflate(txt, "deflatertest.bin")
558
- inflatedTxt = inflate("deflatertest.bin")
559
- assert_equal(txt, inflatedTxt)
560
- end
561
-
562
- private
563
- def load_file(fileName)
564
- txt = nil
565
- File.open(fileName, "rb") { |f| txt = f.read }
566
- end
567
-
568
- def deflate(data, fileName)
569
- File.open(fileName, "wb") {
570
- |file|
571
- deflater = Deflater.new(file)
572
- deflater << data
573
- deflater.finish
574
- assert_equal(deflater.size, data.size)
575
- file << "trailing data for zlib with -MAX_WBITS"
576
- }
577
- end
578
-
579
- def inflate(fileName)
580
- txt = nil
581
- File.open(fileName, "rb") {
582
- |file|
583
- inflater = Inflater.new(file)
584
- txt = inflater.sysread
585
- }
586
- end
587
-
588
- def test_crc
589
- run_crc_test(Deflater)
590
- end
591
- end
592
-
593
- class ZipOutputStreamTest < Test::Unit::TestCase
594
- include AssertEntry
595
-
596
- TEST_ZIP = TestZipFile::TEST_ZIP2.clone
597
- TEST_ZIP.zip_name = "output.zip"
598
-
599
- def test_new
600
- zos = ZipOutputStream.new(TEST_ZIP.zip_name)
601
- zos.comment = TEST_ZIP.comment
602
- write_test_zip(zos)
603
- zos.close
604
- assert_test_zip_contents(TEST_ZIP)
605
- end
606
-
607
- def test_open
608
- ZipOutputStream.open(TEST_ZIP.zip_name) {
609
- |zos|
610
- zos.comment = TEST_ZIP.comment
611
- write_test_zip(zos)
612
- }
613
- assert_test_zip_contents(TEST_ZIP)
614
- end
615
-
616
- def test_writingToClosedStream
617
- assert_i_o_error_in_closed_stream { |zos| zos << "hello world" }
618
- assert_i_o_error_in_closed_stream { |zos| zos.puts "hello world" }
619
- assert_i_o_error_in_closed_stream { |zos| zos.write "hello world" }
620
- end
621
-
622
- def test_cannotOpenFile
623
- name = TestFiles::EMPTY_TEST_DIR
624
- begin
625
- zos = ZipOutputStream.open(name)
626
- rescue Exception
627
- assert($!.kind_of?(Errno::EISDIR) || # Linux
628
- $!.kind_of?(Errno::EEXIST) || # Windows/cygwin
629
- $!.kind_of?(Errno::EACCES), # Windows
630
- "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.class}")
631
- end
632
- end
633
-
634
- def assert_i_o_error_in_closed_stream
635
- assert_raise(IOError) {
636
- zos = ZipOutputStream.new("test_putOnClosedStream.zip")
637
- zos.close
638
- yield zos
639
- }
640
- end
641
-
642
- def write_test_zip(zos)
643
- TEST_ZIP.entry_names.each {
644
- |entryName|
645
- zos.put_next_entry(entryName)
646
- File.open(entryName, "rb") { |f| zos.write(f.read) }
647
- }
648
- end
649
- end
650
-
651
-
652
-
653
- module Enumerable
654
- def compare_enumerables(otherEnumerable)
655
- otherAsArray = otherEnumerable.to_a
656
- index=0
657
- each_with_index {
658
- |element, index|
659
- return false unless yield(element, otherAsArray[index])
660
- }
661
- return index+1 == otherAsArray.size
662
- end
663
- end
664
-
665
-
666
- class ZipCentralDirectoryEntryTest < Test::Unit::TestCase
667
-
668
- def test_read_from_stream
669
- File.open("data/testDirectory.bin", "rb") {
670
- |file|
671
- entry = ZipEntry.read_c_dir_entry(file)
672
-
673
- assert_equal("longAscii.txt", entry.name)
674
- assert_equal(ZipEntry::DEFLATED, entry.compression_method)
675
- assert_equal(106490, entry.size)
676
- assert_equal(3784, entry.compressed_size)
677
- assert_equal(0xfcd1799c, entry.crc)
678
- assert_equal("", entry.comment)
679
-
680
- entry = ZipEntry.read_c_dir_entry(file)
681
- assert_equal("empty.txt", entry.name)
682
- assert_equal(ZipEntry::STORED, entry.compression_method)
683
- assert_equal(0, entry.size)
684
- assert_equal(0, entry.compressed_size)
685
- assert_equal(0x0, entry.crc)
686
- assert_equal("", entry.comment)
687
-
688
- entry = ZipEntry.read_c_dir_entry(file)
689
- assert_equal("short.txt", entry.name)
690
- assert_equal(ZipEntry::STORED, entry.compression_method)
691
- assert_equal(6, entry.size)
692
- assert_equal(6, entry.compressed_size)
693
- assert_equal(0xbb76fe69, entry.crc)
694
- assert_equal("", entry.comment)
695
-
696
- entry = ZipEntry.read_c_dir_entry(file)
697
- assert_equal("longBinary.bin", entry.name)
698
- assert_equal(ZipEntry::DEFLATED, entry.compression_method)
699
- assert_equal(1000024, entry.size)
700
- assert_equal(70847, entry.compressed_size)
701
- assert_equal(0x10da7d59, entry.crc)
702
- assert_equal("", entry.comment)
703
-
704
- entry = ZipEntry.read_c_dir_entry(file)
705
- assert_equal(nil, entry)
706
- # Fields that are not check by this test:
707
- # version made by 2 bytes
708
- # version needed to extract 2 bytes
709
- # general purpose bit flag 2 bytes
710
- # last mod file time 2 bytes
711
- # last mod file date 2 bytes
712
- # compressed size 4 bytes
713
- # uncompressed size 4 bytes
714
- # disk number start 2 bytes
715
- # internal file attributes 2 bytes
716
- # external file attributes 4 bytes
717
- # relative offset of local header 4 bytes
718
-
719
- # file name (variable size)
720
- # extra field (variable size)
721
- # file comment (variable size)
722
-
723
- }
724
- end
725
-
726
- def test_ReadEntryFromTruncatedZipFile
727
- fragment=""
728
- File.open("data/testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
729
- fragment.extend(IOizeString)
730
- entry = ZipEntry.new
731
- entry.read_c_dir_entry(fragment)
732
- fail "ZipError expected"
733
- rescue ZipError
734
- end
735
-
736
- end
737
-
738
-
739
- class ZipEntrySetTest < Test::Unit::TestCase
740
- ZIP_ENTRIES = [
741
- ZipEntry.new("zipfile.zip", "name1", "comment1"),
742
- ZipEntry.new("zipfile.zip", "name2", "comment1"),
743
- ZipEntry.new("zipfile.zip", "name3", "comment1"),
744
- ZipEntry.new("zipfile.zip", "name4", "comment1"),
745
- ZipEntry.new("zipfile.zip", "name5", "comment1"),
746
- ZipEntry.new("zipfile.zip", "name6", "comment1")
747
- ]
748
-
749
- def setup
750
- @zipEntrySet = ZipEntrySet.new(ZIP_ENTRIES)
751
- end
752
-
753
- def test_include
754
- assert(@zipEntrySet.include?(ZIP_ENTRIES.first))
755
- assert(! @zipEntrySet.include?(ZipEntry.new("different.zip", "different", "aComment")))
756
- end
757
-
758
- def test_size
759
- assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
760
- assert_equal(ZIP_ENTRIES.size, @zipEntrySet.length)
761
- @zipEntrySet << ZipEntry.new("a", "b", "c")
762
- assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.length)
763
- end
764
-
765
- def test_add
766
- zes = ZipEntrySet.new
767
- entry1 = ZipEntry.new("zf.zip", "name1")
768
- entry2 = ZipEntry.new("zf.zip", "name2")
769
- zes << entry1
770
- assert(zes.include?(entry1))
771
- zes.push(entry2)
772
- assert(zes.include?(entry2))
773
- end
774
-
775
- def test_delete
776
- assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
777
- entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
778
- assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
779
- assert_equal(ZIP_ENTRIES.first, entry)
780
-
781
- entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
782
- assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
783
- assert_nil(entry)
784
- end
785
-
786
- def test_each
787
- # Tested indirectly via each_with_index
788
- count = 0
789
- @zipEntrySet.each_with_index {
790
- |entry, index|
791
- assert(ZIP_ENTRIES.include?(entry))
792
- count = count.succ
793
- }
794
- assert_equal(ZIP_ENTRIES.size, count)
795
- end
796
-
797
- def test_entries
798
- assert_equal(ZIP_ENTRIES.sort, @zipEntrySet.entries.sort)
799
- end
800
-
801
- def test_compound
802
- newEntry = ZipEntry.new("zf.zip", "new entry", "new entry's comment")
803
- assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
804
- @zipEntrySet << newEntry
805
- assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.size)
806
- assert(@zipEntrySet.include?(newEntry))
807
-
808
- @zipEntrySet.delete(newEntry)
809
- assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
810
- end
811
-
812
- def test_dup
813
- copy = @zipEntrySet.dup
814
- assert_equal(@zipEntrySet, copy)
815
-
816
- # demonstrate that this is a deep copy
817
- copy.entries[0].name = "a totally different name"
818
- assert(@zipEntrySet != copy)
819
- end
820
-
821
- def test_parent
822
- entries = [
823
- ZipEntry.new("zf.zip", "a"),
824
- ZipEntry.new("zf.zip", "a/"),
825
- ZipEntry.new("zf.zip", "a/b"),
826
- ZipEntry.new("zf.zip", "a/b/"),
827
- ZipEntry.new("zf.zip", "a/b/c"),
828
- ZipEntry.new("zf.zip", "a/b/c/")
829
- ]
830
- entrySet = ZipEntrySet.new(entries)
831
-
832
- assert_equal(nil, entrySet.parent(entries[0]))
833
- assert_equal(nil, entrySet.parent(entries[1]))
834
- assert_equal(entries[1], entrySet.parent(entries[2]))
835
- assert_equal(entries[1], entrySet.parent(entries[3]))
836
- assert_equal(entries[3], entrySet.parent(entries[4]))
837
- assert_equal(entries[3], entrySet.parent(entries[5]))
838
- end
839
-
840
- def test_glob
841
- res = @zipEntrySet.glob('name[2-4]')
842
- assert_equal(3, res.size)
843
- assert_equal(ZIP_ENTRIES[1,3], res)
844
- end
845
-
846
- def test_glob2
847
- entries = [
848
- ZipEntry.new("zf.zip", "a/"),
849
- ZipEntry.new("zf.zip", "a/b/b1"),
850
- ZipEntry.new("zf.zip", "a/b/c/"),
851
- ZipEntry.new("zf.zip", "a/b/c/c1")
852
- ]
853
- entrySet = ZipEntrySet.new(entries)
854
-
855
- assert_equal(entries[0,1], entrySet.glob("*"))
856
- # assert_equal(entries[FIXME], entrySet.glob("**"))
857
- # res = entrySet.glob('a*')
858
- # assert_equal(entries.size, res.size)
859
- # assert_equal(entrySet.map { |e| e.name }, res.map { |e| e.name })
860
- end
861
- end
862
-
863
-
864
- class ZipCentralDirectoryTest < Test::Unit::TestCase
865
-
866
- def test_read_from_stream
867
- File.open(TestZipFile::TEST_ZIP2.zip_name, "rb") {
868
- |zipFile|
869
- cdir = ZipCentralDirectory.read_from_stream(zipFile)
870
-
871
- assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size)
872
- assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) {
873
- |cdirEntry, testEntryName|
874
- cdirEntry.name == testEntryName
875
- })
876
- assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment)
877
- }
878
- end
879
-
880
- def test_readFromInvalidStream
881
- File.open("data/file2.txt", "rb") {
882
- |zipFile|
883
- cdir = ZipCentralDirectory.new
884
- cdir.read_from_stream(zipFile)
885
- }
886
- fail "ZipError expected!"
887
- rescue ZipError
888
- end
889
-
890
- def test_ReadFromTruncatedZipFile
891
- fragment=""
892
- File.open("data/testDirectory.bin") { |f| fragment = f.read }
893
- fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
894
- fragment.extend(IOizeString)
895
- entry = ZipCentralDirectory.new
896
- entry.read_from_stream(fragment)
897
- fail "ZipError expected"
898
- rescue ZipError
899
- end
900
-
901
- def test_write_to_stream
902
- entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
903
- ZipEntry.new("file.zip", "secondEntryName"),
904
- ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
905
- cdir = ZipCentralDirectory.new(entries, "my zip comment")
906
- File.open("cdirtest.bin", "wb") { |f| cdir.write_to_stream(f) }
907
- cdirReadback = ZipCentralDirectory.new
908
- File.open("cdirtest.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
909
-
910
- assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
911
- end
912
-
913
- def test_equality
914
- cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
915
- "somethingExtra"),
916
- ZipEntry.new("file.zip", "secondEntryName"),
917
- ZipEntry.new("file.zip", "lastEntry.txt") ],
918
- "my zip comment")
919
- cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
920
- "somethingExtra"),
921
- ZipEntry.new("file.zip", "secondEntryName"),
922
- ZipEntry.new("file.zip", "lastEntry.txt") ],
923
- "my zip comment")
924
- cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
925
- "somethingExtra"),
926
- ZipEntry.new("file.zip", "secondEntryName"),
927
- ZipEntry.new("file.zip", "lastEntry.txt") ],
928
- "comment?")
929
- cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
930
- "somethingExtra"),
931
- ZipEntry.new("file.zip", "lastEntry.txt") ],
932
- "comment?")
933
- assert_equal(cdir1, cdir1)
934
- assert_equal(cdir1, cdir2)
935
-
936
- assert(cdir1 != cdir3)
937
- assert(cdir2 != cdir3)
938
- assert(cdir2 != cdir3)
939
- assert(cdir3 != cdir4)
940
-
941
- assert(cdir3 != "hello")
942
- end
943
- end
944
-
945
-
946
- class BasicZipFileTest < Test::Unit::TestCase
947
- include AssertEntry
948
-
949
- def setup
950
- @zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zip_name)
951
- @testEntryNameIndex=0
952
- end
953
-
954
- def test_entries
955
- assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort,
956
- @zipFile.entries.entries.sort.map {|e| e.name} )
957
- end
958
-
959
- def test_each
960
- count = 0
961
- visited = {}
962
- @zipFile.each {
963
- |entry|
964
- assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
965
- assert(! visited.include?(entry.name))
966
- visited[entry.name] = nil
967
- count = count.succ
968
- }
969
- assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
970
- end
971
-
972
- def test_foreach
973
- count = 0
974
- visited = {}
975
- ZipFile.foreach(TestZipFile::TEST_ZIP2.zip_name) {
976
- |entry|
977
- assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
978
- assert(! visited.include?(entry.name))
979
- visited[entry.name] = nil
980
- count = count.succ
981
- }
982
- assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
983
- end
984
-
985
- def test_get_input_stream
986
- count = 0
987
- visited = {}
988
- @zipFile.each {
989
- |entry|
990
- assert_entry(entry.name, @zipFile.get_input_stream(entry), entry.name)
991
- assert(! visited.include?(entry.name))
992
- visited[entry.name] = nil
993
- count = count.succ
994
- }
995
- assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
996
- end
997
-
998
- def test_get_input_streamBlock
999
- fileAndEntryName = @zipFile.entries.first.name
1000
- @zipFile.get_input_stream(fileAndEntryName) {
1001
- |zis|
1002
- assert_entryContentsForStream(fileAndEntryName,
1003
- zis,
1004
- fileAndEntryName)
1005
- }
1006
- end
1007
- end
1008
-
1009
- module CommonZipFileFixture
1010
- include AssertEntry
1011
-
1012
- EMPTY_FILENAME = "emptyZipFile.zip"
1013
-
1014
- TEST_ZIP = TestZipFile::TEST_ZIP2.clone
1015
- TEST_ZIP.zip_name = "5entry_copy.zip"
1016
-
1017
- def setup
1018
- File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
1019
- File.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
1020
- end
1021
- end
1022
-
1023
- class ZipFileTest < Test::Unit::TestCase
1024
- include CommonZipFileFixture
1025
-
1026
- def test_createFromScratch
1027
- comment = "a short comment"
1028
-
1029
- zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1030
- zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
1031
- zf.mkdir("dir1")
1032
- zf.comment = comment
1033
- zf.close
1034
-
1035
- zfRead = ZipFile.new(EMPTY_FILENAME)
1036
- assert_equal(comment, zfRead.comment)
1037
- assert_equal(2, zfRead.entries.length)
1038
- end
1039
-
1040
- def test_get_output_stream
1041
- entryCount = nil
1042
- ZipFile.open(TEST_ZIP.zip_name) {
1043
- |zf|
1044
- entryCount = zf.size
1045
- zf.get_output_stream('newEntry.txt') {
1046
- |os|
1047
- os.write "Putting stuff in newEntry.txt"
1048
- }
1049
- assert_equal(entryCount+1, zf.size)
1050
- assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
1051
-
1052
- zf.get_output_stream(zf.get_entry('data/generated/empty.txt')) {
1053
- |os|
1054
- os.write "Putting stuff in data/generated/empty.txt"
1055
- }
1056
- assert_equal(entryCount+1, zf.size)
1057
- assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
1058
-
1059
- zf.get_output_stream('entry.bin') {
1060
- |os|
1061
- os.write(File.open('data/generated/5entry.zip', 'rb').read)
1062
- }
1063
- }
1064
-
1065
- ZipFile.open(TEST_ZIP.zip_name) {
1066
- |zf|
1067
- assert_equal(entryCount+2, zf.size)
1068
- assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
1069
- assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
1070
- assert_equal(File.open('data/generated/5entry.zip', 'rb').read, zf.read("entry.bin"))
1071
- }
1072
- end
1073
-
1074
- def test_add
1075
- srcFile = "data/file2.txt"
1076
- entryName = "newEntryName.rb"
1077
- assert(File.exists?(srcFile))
1078
- zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1079
- zf.add(entryName, srcFile)
1080
- zf.close
1081
-
1082
- zfRead = ZipFile.new(EMPTY_FILENAME)
1083
- assert_equal("", zfRead.comment)
1084
- assert_equal(1, zfRead.entries.length)
1085
- assert_equal(entryName, zfRead.entries.first.name)
1086
- AssertEntry.assert_contents(srcFile,
1087
- zfRead.get_input_stream(entryName) { |zis| zis.read })
1088
- end
1089
-
1090
- def test_addExistingEntryName
1091
- assert_raise(ZipEntryExistsError) {
1092
- ZipFile.open(TEST_ZIP.zip_name) {
1093
- |zf|
1094
- zf.add(zf.entries.first.name, "data/file2.txt")
1095
- }
1096
- }
1097
- end
1098
-
1099
- def test_addExistingEntryNameReplace
1100
- gotCalled = false
1101
- replacedEntry = nil
1102
- ZipFile.open(TEST_ZIP.zip_name) {
1103
- |zf|
1104
- replacedEntry = zf.entries.first.name
1105
- zf.add(replacedEntry, "data/file2.txt") { gotCalled = true; true }
1106
- }
1107
- assert(gotCalled)
1108
- ZipFile.open(TEST_ZIP.zip_name) {
1109
- |zf|
1110
- assert_contains(zf, replacedEntry, "data/file2.txt")
1111
- }
1112
- end
1113
-
1114
- def test_addDirectory
1115
- ZipFile.open(TEST_ZIP.zip_name) {
1116
- |zf|
1117
- zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
1118
- }
1119
- ZipFile.open(TEST_ZIP.zip_name) {
1120
- |zf|
1121
- dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
1122
- assert(dirEntry.is_directory)
1123
- }
1124
- end
1125
-
1126
- def test_remove
1127
- entryToRemove, *remainingEntries = TEST_ZIP.entry_names
1128
-
1129
- File.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
1130
-
1131
- zf = ZipFile.new(TEST_ZIP.zip_name)
1132
- assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
1133
- zf.remove(entryToRemove)
1134
- assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
1135
- assert_equal(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
1136
- zf.close
1137
-
1138
- zfRead = ZipFile.new(TEST_ZIP.zip_name)
1139
- assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
1140
- assert_equal(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
1141
- zfRead.close
1142
- end
1143
-
1144
-
1145
- def test_rename
1146
- entryToRename, *remainingEntries = TEST_ZIP.entry_names
1147
-
1148
- zf = ZipFile.new(TEST_ZIP.zip_name)
1149
- assert(zf.entries.map { |e| e.name }.include?(entryToRename))
1150
-
1151
- newName = "changed name"
1152
- assert(! zf.entries.map { |e| e.name }.include?(newName))
1153
-
1154
- zf.rename(entryToRename, newName)
1155
- assert(zf.entries.map { |e| e.name }.include?(newName))
1156
-
1157
- zf.close
1158
-
1159
- zfRead = ZipFile.new(TEST_ZIP.zip_name)
1160
- assert(zfRead.entries.map { |e| e.name }.include?(newName))
1161
- zfRead.close
1162
- end
1163
-
1164
- def test_renameToExistingEntry
1165
- oldEntries = nil
1166
- ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1167
-
1168
- assert_raise(ZipEntryExistsError) {
1169
- ZipFile.open(TEST_ZIP.zip_name) {
1170
- |zf|
1171
- zf.rename(zf.entries[0], zf.entries[1].name)
1172
- }
1173
- }
1174
-
1175
- ZipFile.open(TEST_ZIP.zip_name) {
1176
- |zf|
1177
- assert_equal(oldEntries.sort.map{ |e| e.name }, zf.entries.sort.map{ |e| e.name })
1178
- }
1179
- end
1180
-
1181
- def test_renameToExistingEntryOverwrite
1182
- oldEntries = nil
1183
- ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1184
-
1185
- gotCalled = false
1186
- renamedEntryName = nil
1187
- ZipFile.open(TEST_ZIP.zip_name) {
1188
- |zf|
1189
- renamedEntryName = zf.entries[0].name
1190
- zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
1191
- }
1192
-
1193
- assert(gotCalled)
1194
- oldEntries.delete_if { |e| e.name == renamedEntryName }
1195
- ZipFile.open(TEST_ZIP.zip_name) {
1196
- |zf|
1197
- assert_equal(oldEntries.sort.map{ |e| e.name },
1198
- zf.entries.sort.map{ |e| e.name })
1199
- }
1200
- end
1201
-
1202
- def test_renameNonEntry
1203
- nonEntry = "bogusEntry"
1204
- target_entry = "target_entryName"
1205
- zf = ZipFile.new(TEST_ZIP.zip_name)
1206
- assert(! zf.entries.include?(nonEntry))
1207
- assert_raise(Errno::ENOENT) {
1208
- zf.rename(nonEntry, target_entry)
1209
- }
1210
- zf.commit
1211
- assert(! zf.entries.include?(target_entry))
1212
- ensure
1213
- zf.close
1214
- end
1215
-
1216
- def test_renameEntryToExistingEntry
1217
- entry1, entry2, *remaining = TEST_ZIP.entry_names
1218
- zf = ZipFile.new(TEST_ZIP.zip_name)
1219
- assert_raise(ZipEntryExistsError) {
1220
- zf.rename(entry1, entry2)
1221
- }
1222
- ensure
1223
- zf.close
1224
- end
1225
-
1226
- def test_replace
1227
- entryToReplace = TEST_ZIP.entry_names[2]
1228
- newEntrySrcFilename = "data/file2.txt"
1229
- zf = ZipFile.new(TEST_ZIP.zip_name)
1230
- zf.replace(entryToReplace, newEntrySrcFilename)
1231
-
1232
- zf.close
1233
- zfRead = ZipFile.new(TEST_ZIP.zip_name)
1234
- AssertEntry::assert_contents(newEntrySrcFilename,
1235
- zfRead.get_input_stream(entryToReplace) { |is| is.read })
1236
- AssertEntry::assert_contents(TEST_ZIP.entry_names[0],
1237
- zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read })
1238
- AssertEntry::assert_contents(TEST_ZIP.entry_names[1],
1239
- zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read })
1240
- AssertEntry::assert_contents(TEST_ZIP.entry_names[3],
1241
- zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read })
1242
- zfRead.close
1243
- end
1244
-
1245
- def test_replaceNonEntry
1246
- entryToReplace = "nonExistingEntryname"
1247
- ZipFile.open(TEST_ZIP.zip_name) {
1248
- |zf|
1249
- assert_raise(Errno::ENOENT) {
1250
- zf.replace(entryToReplace, "data/file2.txt")
1251
- }
1252
- }
1253
- end
1254
-
1255
- def test_commit
1256
- newName = "renamedFirst"
1257
- zf = ZipFile.new(TEST_ZIP.zip_name)
1258
- oldName = zf.entries.first
1259
- zf.rename(oldName, newName)
1260
- zf.commit
1261
-
1262
- zfRead = ZipFile.new(TEST_ZIP.zip_name)
1263
- assert(zfRead.entries.detect { |e| e.name == newName } != nil)
1264
- assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
1265
- zfRead.close
1266
-
1267
- zf.close
1268
- end
1269
-
1270
- # This test tests that after commit, you
1271
- # can delete the file you used to add the entry to the zip file
1272
- # with
1273
- def test_commitUseZipEntry
1274
- File.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
1275
- zf = ZipFile.open(TEST_ZIP.zip_name)
1276
- zf.add("okToDelete.txt", "okToDelete.txt")
1277
- assert_contains(zf, "okToDelete.txt")
1278
- zf.commit
1279
- File.move("okToDelete.txt", "okToDeleteMoved.txt")
1280
- assert_contains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
1281
- end
1282
-
1283
- # def test_close
1284
- # zf = ZipFile.new(TEST_ZIP.zip_name)
1285
- # zf.close
1286
- # assert_raise(IOError) {
1287
- # zf.extract(TEST_ZIP.entry_names.first, "hullubullu")
1288
- # }
1289
- # end
1290
-
1291
- def test_compound1
1292
- renamedName = "renamedName"
1293
- originalEntries = []
1294
- begin
1295
- zf = ZipFile.new(TEST_ZIP.zip_name)
1296
- originalEntries = zf.entries.dup
1297
-
1298
- assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1299
- zf.add(TestFiles::RANDOM_ASCII_FILE1,
1300
- TestFiles::RANDOM_ASCII_FILE1)
1301
- assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1302
-
1303
- zf.rename(zf.entries[0], renamedName)
1304
- assert_contains(zf, renamedName)
1305
-
1306
- TestFiles::BINARY_TEST_FILES.each {
1307
- |filename|
1308
- zf.add(filename, filename)
1309
- assert_contains(zf, filename)
1310
- }
1311
-
1312
- assert_contains(zf, originalEntries.last.to_s)
1313
- zf.remove(originalEntries.last.to_s)
1314
- assert_not_contains(zf, originalEntries.last.to_s)
1315
-
1316
- ensure
1317
- zf.close
1318
- end
1319
- begin
1320
- zfRead = ZipFile.new(TEST_ZIP.zip_name)
1321
- assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
1322
- assert_contains(zfRead, renamedName)
1323
- TestFiles::BINARY_TEST_FILES.each {
1324
- |filename|
1325
- assert_contains(zfRead, filename)
1326
- }
1327
- assert_not_contains(zfRead, originalEntries.last.to_s)
1328
- ensure
1329
- zfRead.close
1330
- end
1331
- end
1332
-
1333
- def test_compound2
1334
- begin
1335
- zf = ZipFile.new(TEST_ZIP.zip_name)
1336
- originalEntries = zf.entries.dup
1337
-
1338
- originalEntries.each {
1339
- |entry|
1340
- zf.remove(entry)
1341
- assert_not_contains(zf, entry)
1342
- }
1343
- assert(zf.entries.empty?)
1344
-
1345
- TestFiles::ASCII_TEST_FILES.each {
1346
- |filename|
1347
- zf.add(filename, filename)
1348
- assert_contains(zf, filename)
1349
- }
1350
- assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
1351
-
1352
- zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
1353
- assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0])
1354
- assert_contains(zf, "newName")
1355
- ensure
1356
- zf.close
1357
- end
1358
- begin
1359
- zfRead = ZipFile.new(TEST_ZIP.zip_name)
1360
- asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
1361
- asciiTestFiles.shift
1362
- asciiTestFiles.each {
1363
- |filename|
1364
- assert_contains(zf, filename)
1365
- }
1366
-
1367
- assert_contains(zf, "newName")
1368
- ensure
1369
- zfRead.close
1370
- end
1371
- end
1372
-
1373
- private
1374
- def assert_contains(zf, entryName, filename = entryName)
1375
- assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
1376
- assert_entryContents(zf, entryName, filename) if File.exists?(filename)
1377
- end
1378
-
1379
- def assert_not_contains(zf, entryName)
1380
- assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
1381
- end
1382
- end
1383
-
1384
- class ZipFileExtractTest < Test::Unit::TestCase
1385
- include CommonZipFileFixture
1386
- EXTRACTED_FILENAME = "extEntry"
1387
- ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entry_names.reverse
1388
-
1389
- def setup
1390
- super
1391
- File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
1392
- end
1393
-
1394
- def test_extract
1395
- ZipFile.open(TEST_ZIP.zip_name) {
1396
- |zf|
1397
- zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
1398
-
1399
- assert(File.exists?(EXTRACTED_FILENAME))
1400
- AssertEntry::assert_contents(EXTRACTED_FILENAME,
1401
- zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
1402
-
1403
-
1404
- File::unlink(EXTRACTED_FILENAME)
1405
-
1406
- entry = zf.get_entry(ENTRY_TO_EXTRACT)
1407
- entry.extract(EXTRACTED_FILENAME)
1408
-
1409
- assert(File.exists?(EXTRACTED_FILENAME))
1410
- AssertEntry::assert_contents(EXTRACTED_FILENAME,
1411
- entry.get_input_stream() { |is| is.read })
1412
-
1413
- }
1414
- end
1415
-
1416
- def test_extractExists
1417
- writtenText = "written text"
1418
- File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1419
-
1420
- assert_raise(ZipDestinationFileExistsError) {
1421
- ZipFile.open(TEST_ZIP.zip_name) {
1422
- |zf|
1423
- zf.extract(zf.entries.first, EXTRACTED_FILENAME)
1424
- }
1425
- }
1426
- File.open(EXTRACTED_FILENAME, "r") {
1427
- |f|
1428
- assert_equal(writtenText, f.read)
1429
- }
1430
- end
1431
-
1432
- def test_extractExistsOverwrite
1433
- writtenText = "written text"
1434
- File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1435
-
1436
- gotCalledCorrectly = false
1437
- ZipFile.open(TEST_ZIP.zip_name) {
1438
- |zf|
1439
- zf.extract(zf.entries.first, EXTRACTED_FILENAME) {
1440
- |entry, extractLoc|
1441
- gotCalledCorrectly = zf.entries.first == entry &&
1442
- extractLoc == EXTRACTED_FILENAME
1443
- true
1444
- }
1445
- }
1446
-
1447
- assert(gotCalledCorrectly)
1448
- File.open(EXTRACTED_FILENAME, "r") {
1449
- |f|
1450
- assert(writtenText != f.read)
1451
- }
1452
- end
1453
-
1454
- def test_extractNonEntry
1455
- zf = ZipFile.new(TEST_ZIP.zip_name)
1456
- assert_raise(Errno::ENOENT) { zf.extract("nonExistingEntry", "nonExistingEntry") }
1457
- ensure
1458
- zf.close if zf
1459
- end
1460
-
1461
- def test_extractNonEntry2
1462
- outFile = "outfile"
1463
- assert_raise(Errno::ENOENT) {
1464
- zf = ZipFile.new(TEST_ZIP.zip_name)
1465
- nonEntry = "hotdog-diddelidoo"
1466
- assert(! zf.entries.include?(nonEntry))
1467
- zf.extract(nonEntry, outFile)
1468
- zf.close
1469
- }
1470
- assert(! File.exists?(outFile))
1471
- end
1472
-
1473
- end
1474
-
1475
- class ZipFileExtractDirectoryTest < Test::Unit::TestCase
1476
- include CommonZipFileFixture
1477
- TEST_OUT_NAME = "emptyOutDir"
1478
-
1479
- def open_zip(&aProc)
1480
- assert(aProc != nil)
1481
- ZipFile.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
1482
- end
1483
-
1484
- def extract_test_dir(&aProc)
1485
- open_zip {
1486
- |zf|
1487
- zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
1488
- }
1489
- end
1490
-
1491
- def setup
1492
- super
1493
-
1494
- Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
1495
- File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
1496
- end
1497
-
1498
- def test_extractDirectory
1499
- extract_test_dir
1500
- assert(File.directory?(TEST_OUT_NAME))
1501
- end
1502
-
1503
- def test_extractDirectoryExistsAsDir
1504
- Dir.mkdir TEST_OUT_NAME
1505
- extract_test_dir
1506
- assert(File.directory?(TEST_OUT_NAME))
1507
- end
1508
-
1509
- def test_extractDirectoryExistsAsFile
1510
- File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1511
- assert_raise(ZipDestinationFileExistsError) { extract_test_dir }
1512
- end
1513
-
1514
- def test_extractDirectoryExistsAsFileOverwrite
1515
- File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1516
- gotCalled = false
1517
- extract_test_dir {
1518
- |entry, destPath|
1519
- gotCalled = true
1520
- assert_equal(TEST_OUT_NAME, destPath)
1521
- assert(entry.is_directory)
1522
- true
1523
- }
1524
- assert(gotCalled)
1525
- assert(File.directory?(TEST_OUT_NAME))
1526
- end
1527
- end
1528
-
1529
- class ZipExtraFieldTest < Test::Unit::TestCase
1530
- def test_new
1531
- extra_pure = ZipExtraField.new("")
1532
- extra_withstr = ZipExtraField.new("foo")
1533
- assert_instance_of(ZipExtraField, extra_pure)
1534
- assert_instance_of(ZipExtraField, extra_withstr)
1535
- end
1536
-
1537
- def test_unknownfield
1538
- extra = ZipExtraField.new("foo")
1539
- assert_equal(extra["Unknown"], "foo")
1540
- extra.merge("a")
1541
- assert_equal(extra["Unknown"], "fooa")
1542
- extra.merge("barbaz")
1543
- assert_equal(extra.to_s, "fooabarbaz")
1544
- end
1545
-
1546
-
1547
- def test_merge
1548
- str = "UT\x5\0\x3\250$\r@Ux\0\0"
1549
- extra1 = ZipExtraField.new("")
1550
- extra2 = ZipExtraField.new(str)
1551
- assert(! extra1.member?("UniversalTime"))
1552
- assert(extra2.member?("UniversalTime"))
1553
- extra1.merge(str)
1554
- assert_equal(extra1["UniversalTime"].mtime, extra2["UniversalTime"].mtime)
1555
- end
1556
-
1557
- def test_length
1558
- str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1559
- extra = ZipExtraField.new(str)
1560
- assert_equal(extra.local_length, extra.to_local_bin.length)
1561
- assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1562
- extra.merge("foo")
1563
- assert_equal(extra.local_length, extra.to_local_bin.length)
1564
- assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1565
- end
1566
-
1567
-
1568
- def test_to_s
1569
- str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1570
- extra = ZipExtraField.new(str)
1571
- assert_instance_of(String, extra.to_s)
1572
-
1573
- s = extra.to_s
1574
- extra.merge("foo")
1575
- assert_equal(s.length + 3, extra.to_s.length)
1576
- end
1577
-
1578
- def test_equality
1579
- str = "UT\x5\0\x3\250$\r@"
1580
- extra1 = ZipExtraField.new(str)
1581
- extra2 = ZipExtraField.new(str)
1582
- extra3 = ZipExtraField.new(str)
1583
- assert_equal(extra1, extra2)
1584
-
1585
- extra2["UniversalTime"].mtime = Time.now
1586
- assert(extra1 != extra2)
1587
-
1588
- extra3.create("IUnix")
1589
- assert(extra1 != extra3)
1590
-
1591
- extra1.create("IUnix")
1592
- assert_equal(extra1, extra3)
1593
- end
1594
-
1595
- end
1596
-
1597
- # Copyright (C) 2002-2005 Thomas Sondergaard
1598
- # rubyzip is free software; you can redistribute it and/or
1599
- # modify it under the terms of the ruby license.