rubyzip 0.5.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubyzip might be problematic. Click here for more details.

@@ -0,0 +1,90 @@
1
+ # With ziprequire you can load ruby modules from a zip file. This means
2
+ # ruby's module include path can include zip-files.
3
+ #
4
+ # The following example creates a zip file with a single entry
5
+ # <code>log/simplelog.rb</code> that contains a single function
6
+ # <code>simpleLog</code>:
7
+ #
8
+ # require 'zip/zipfilesystem'
9
+ #
10
+ # Zip::ZipFile.open("my.zip", true) {
11
+ # |zf|
12
+ # zf.file.open("log/simplelog.rb", "w") {
13
+ # |f|
14
+ # f.puts "def simpleLog(v)"
15
+ # f.puts ' Kernel.puts "INFO: #{v}"'
16
+ # f.puts "end"
17
+ # }
18
+ # }
19
+ #
20
+ # To use the ruby module stored in the zip archive simply require
21
+ # <code>zip/ziprequire</code> and include the <code>my.zip</code> zip
22
+ # file in the module search path. The following command shows one
23
+ # way to do this:
24
+ #
25
+ # ruby -rzip/ziprequire -Imy.zip -e " require 'log/simplelog'; simpleLog 'Hello world' "
26
+
27
+ #$: << 'data/rubycode.zip' << 'data/rubycode2.zip'
28
+
29
+
30
+ require 'zip/zip'
31
+
32
+ class ZipList #:nodoc:all
33
+ def initialize(zipFileList)
34
+ @zipFileList = zipFileList
35
+ end
36
+
37
+ def get_input_stream(entry, &aProc)
38
+ @zipFileList.each {
39
+ |zfName|
40
+ Zip::ZipFile.open(zfName) {
41
+ |zf|
42
+ begin
43
+ return zf.get_input_stream(entry, &aProc)
44
+ rescue Errno::ENOENT
45
+ end
46
+ }
47
+ }
48
+ raise Errno::ENOENT,
49
+ "No matching entry found in zip files '#{@zipFileList.join(', ')}' "+
50
+ " for '#{entry}'"
51
+ end
52
+ end
53
+
54
+
55
+ module Kernel #:nodoc:all
56
+ alias :oldRequire :require
57
+
58
+ def require(moduleName)
59
+ zip_require(moduleName) || oldRequire(moduleName)
60
+ end
61
+
62
+ def zip_require(moduleName)
63
+ return false if already_loaded?(moduleName)
64
+ get_resource(ensure_rb_extension(moduleName)) {
65
+ |zis|
66
+ eval(zis.read); $" << moduleName
67
+ }
68
+ return true
69
+ rescue Errno::ENOENT => ex
70
+ return false
71
+ end
72
+
73
+ def get_resource(resourceName, &aProc)
74
+ zl = ZipList.new($:.grep(/\.zip$/))
75
+ zl.get_input_stream(resourceName, &aProc)
76
+ end
77
+
78
+ def already_loaded?(moduleName)
79
+ moduleRE = Regexp.new("^"+moduleName+"(\.rb|\.so|\.dll|\.o)?$")
80
+ $".detect { |e| e =~ moduleRE } != nil
81
+ end
82
+
83
+ def ensure_rb_extension(aString)
84
+ aString.sub(/(\.rb)?$/i, ".rb")
85
+ end
86
+ end
87
+
88
+ # Copyright (C) 2002 Thomas Sondergaard
89
+ # rubyzip is free software; you can redistribute it and/or
90
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << "../lib"
4
+ system("zip example.zip example.rb gtkRubyzip.rb")
5
+
6
+ require 'zip/zip'
7
+
8
+ ####### Using ZipInputStream alone: #######
9
+
10
+ Zip::ZipInputStream.open("example.zip") {
11
+ |zis|
12
+ entry = zis.get_next_entry
13
+ print "First line of '#{entry.name} (#{entry.size} bytes): "
14
+ puts "'#{zis.gets.chomp}'"
15
+ entry = zis.get_next_entry
16
+ print "First line of '#{entry.name} (#{entry.size} bytes): "
17
+ puts "'#{zis.gets.chomp}'"
18
+ }
19
+
20
+
21
+ ####### Using ZipFile to read the directory of a zip file: #######
22
+
23
+ zf = Zip::ZipFile.new("example.zip")
24
+ zf.each_with_index {
25
+ |entry, index|
26
+
27
+ puts "entry #{index} is #{entry.name}, size = #{entry.size}, compressed size = #{entry.compressed_size}"
28
+ # use zf.get_input_stream(entry) to get a ZipInputStream for the entry
29
+ # entry can be the ZipEntry object or any object which has a to_s method that
30
+ # returns the name of the entry.
31
+ }
32
+
33
+
34
+ ####### Using ZipOutputStream to write a zip file: #######
35
+
36
+ Zip::ZipOutputStream.open("exampleout.zip") {
37
+ |zos|
38
+ zos.put_next_entry("the first little entry")
39
+ zos.puts "Hello hello hello hello hello hello hello hello hello"
40
+
41
+ zos.put_next_entry("the second little entry")
42
+ zos.puts "Hello again"
43
+
44
+ # Use rubyzip or your zip client of choice to verify
45
+ # the contents of exampleout.zip
46
+ }
47
+
48
+ ####### Using ZipFile to change a zip file: #######
49
+
50
+ Zip::ZipFile.open("exampleout.zip") {
51
+ |zf|
52
+ zf.add("thisFile.rb", "example.rb")
53
+ zf.rename("thisFile.rb", "ILikeThisName.rb")
54
+ zf.add("Again", "example.rb")
55
+ }
56
+
57
+ # Lets check
58
+ Zip::ZipFile.open("exampleout.zip") {
59
+ |zf|
60
+ puts "Changed zip file contains: #{zf.entries.join(', ')}"
61
+ zf.remove("Again")
62
+ puts "Without 'Again': #{zf.entries.join(', ')}"
63
+ }
64
+
65
+ # For other examples, look at zip.rb and ziptest.rb
66
+
67
+ # Copyright (C) 2002 Thomas Sondergaard
68
+ # rubyzip is free software; you can redistribute it and/or
69
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << "../lib"
4
+
5
+ require 'zip/zipfilesystem'
6
+ require 'ftools'
7
+
8
+ EXAMPLE_ZIP = "filesystem.zip"
9
+
10
+ File.delete(EXAMPLE_ZIP) if File.exists?(EXAMPLE_ZIP)
11
+
12
+ Zip::ZipFile.open(EXAMPLE_ZIP, Zip::ZipFile::CREATE) {
13
+ |zf|
14
+ zf.file.open("file1.txt", "w") { |os| os.write "first file1.txt" }
15
+ zf.dir.mkdir("dir1")
16
+ zf.dir.chdir("dir1")
17
+ zf.file.open("file1.txt", "w") { |os| os.write "second file1.txt" }
18
+ puts zf.file.read("file1.txt")
19
+ puts zf.file.read("../file1.txt")
20
+ zf.dir.chdir("..")
21
+ zf.file.open("file2.txt", "w") { |os| os.write "first file2.txt" }
22
+ puts "Entries: #{zf.entries.join(', ')}"
23
+ }
24
+
25
+ Zip::ZipFile.open(EXAMPLE_ZIP) {
26
+ |zf|
27
+ puts "Entries from reloaded zip: #{zf.entries.join(', ')}"
28
+ }
29
+
30
+ # For other examples, look at zip.rb and ziptest.rb
31
+
32
+ # Copyright (C) 2003 Thomas Sondergaard
33
+ # rubyzip is free software; you can redistribute it and/or
34
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << "../lib"
4
+
5
+ $VERBOSE = true
6
+
7
+ require 'gtk'
8
+ require 'zip/zip'
9
+
10
+ class MainApp < Gtk::Window
11
+ def initialize
12
+ super()
13
+ set_usize(400, 256)
14
+ set_title("rubyzip")
15
+ signal_connect(Gtk::Window::SIGNAL_DESTROY) { Gtk.main_quit }
16
+
17
+ box = Gtk::VBox.new(false, 0)
18
+ add(box)
19
+
20
+ @zipfile = nil
21
+ @buttonPanel = ButtonPanel.new
22
+ @buttonPanel.openButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
23
+ show_file_selector
24
+ }
25
+ @buttonPanel.extractButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
26
+ puts "Not implemented!"
27
+ }
28
+ box.pack_start(@buttonPanel, false, false, 0)
29
+
30
+ sw = Gtk::ScrolledWindow.new
31
+ sw.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
32
+ box.pack_start(sw, true, true, 0)
33
+
34
+ @clist = Gtk::CList.new(["Name", "Size", "Compression"])
35
+ @clist.set_selection_mode(Gtk::SELECTION_BROWSE)
36
+ @clist.set_column_width(0, 120)
37
+ @clist.set_column_width(1, 120)
38
+ @clist.signal_connect(Gtk::CList::SIGNAL_SELECT_ROW) {
39
+ |w, row, column, event|
40
+ @selected_row = row
41
+ }
42
+ sw.add(@clist)
43
+ end
44
+
45
+ class ButtonPanel < Gtk::HButtonBox
46
+ attr_reader :openButton, :extractButton
47
+ def initialize
48
+ super
49
+ set_layout(Gtk::BUTTONBOX_START)
50
+ set_spacing(0)
51
+ @openButton = Gtk::Button.new("Open archive")
52
+ @extractButton = Gtk::Button.new("Extract entry")
53
+ pack_start(@openButton)
54
+ pack_start(@extractButton)
55
+ end
56
+ end
57
+
58
+ def show_file_selector
59
+ @fileSelector = Gtk::FileSelection.new("Open zip file")
60
+ @fileSelector.show
61
+ @fileSelector.ok_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
62
+ open_zip(@fileSelector.filename)
63
+ @fileSelector.destroy
64
+ }
65
+ @fileSelector.cancel_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) {
66
+ @fileSelector.destroy
67
+ }
68
+ end
69
+
70
+ def open_zip(filename)
71
+ @zipfile = Zip::ZipFile.open(filename)
72
+ @clist.clear
73
+ @zipfile.each {
74
+ |entry|
75
+ @clist.append([ entry.name,
76
+ entry.size.to_s,
77
+ (100.0*entry.compressedSize/entry.size).to_s+"%" ])
78
+ }
79
+ end
80
+ end
81
+
82
+ mainApp = MainApp.new()
83
+
84
+ mainApp.show_all
85
+
86
+ Gtk.main
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << "../lib"
4
+
5
+ require 'zip/zip'
6
+
7
+ include Zip
8
+
9
+ ZipOutputStream.open('simple.zip') {
10
+ |zos|
11
+ ze = zos.put_next_entry 'entry.txt'
12
+ zos.puts "Hello world"
13
+ }
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $VERBOSE = true
4
+
5
+ $: << "../lib"
6
+
7
+ require 'zip/zip'
8
+ require 'find'
9
+
10
+ module Zip
11
+ module ZipFind
12
+ def self.find(path, zipFilePattern = /\.zip$/i)
13
+ Find.find(path) {
14
+ |fileName|
15
+ yield(fileName)
16
+ if zipFilePattern.match(fileName) && File.file?(fileName)
17
+ begin
18
+ Zip::ZipFile.foreach(fileName) {
19
+ |zipEntry|
20
+ yield(fileName + File::SEPARATOR + zipEntry.to_s)
21
+ }
22
+ rescue Errno::EACCES => ex
23
+ puts ex
24
+ end
25
+ end
26
+ }
27
+ end
28
+
29
+ def self.find_file(path, fileNamePattern, zipFilePattern = /\.zip$/i)
30
+ self.find(path, zipFilePattern) {
31
+ |fileName|
32
+ yield(fileName) if fileNamePattern.match(fileName)
33
+ }
34
+ end
35
+
36
+ end
37
+ end
38
+
39
+ if __FILE__ == $0
40
+ module ZipFindConsoleRunner
41
+
42
+ PATH_ARG_INDEX = 0;
43
+ FILENAME_PATTERN_ARG_INDEX = 1;
44
+ ZIPFILE_PATTERN_ARG_INDEX = 2;
45
+
46
+ def self.run(args)
47
+ check_args(args)
48
+ Zip::ZipFind.find_file(args[PATH_ARG_INDEX],
49
+ args[FILENAME_PATTERN_ARG_INDEX],
50
+ args[ZIPFILE_PATTERN_ARG_INDEX]) {
51
+ |fileName|
52
+ report_entry_found fileName
53
+ }
54
+ end
55
+
56
+ def self.check_args(args)
57
+ if (args.size != 3)
58
+ usage
59
+ exit
60
+ end
61
+ end
62
+
63
+ def self.usage
64
+ puts "Usage: #{$0} PATH ZIPFILENAME_PATTERN FILNAME_PATTERN"
65
+ end
66
+
67
+ def self.report_entry_found(fileName)
68
+ puts fileName
69
+ end
70
+
71
+ end
72
+
73
+ ZipFindConsoleRunner.run(ARGV)
74
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $VERBOSE = true
4
+
5
+ require 'stdrubyexttest'
6
+ require 'ioextrastest'
7
+ require 'ziptest'
8
+ require 'zipfilesystemtest'
9
+ require 'ziprequiretest'
@@ -0,0 +1,46 @@
1
+
2
+ AUTOMAKE_OPTIONS = gnu
3
+
4
+ EXTRA_DIST = test.zip
5
+
6
+ CXXFLAGS= -g
7
+
8
+ noinst_LIBRARIES = libzipios.a
9
+
10
+ bin_PROGRAMS = test_zip test_izipfilt test_izipstream
11
+ # test_flist
12
+
13
+ libzipios_a_SOURCES = backbuffer.h fcol.cpp fcol.h \
14
+ fcol_common.h fcolexceptions.cpp fcolexceptions.h \
15
+ fileentry.cpp fileentry.h flist.cpp \
16
+ flist.h flistentry.cpp flistentry.h \
17
+ flistscanner.h ifiltstreambuf.cpp ifiltstreambuf.h \
18
+ inflatefilt.cpp inflatefilt.h izipfilt.cpp \
19
+ izipfilt.h izipstream.cpp izipstream.h \
20
+ zipfile.cpp zipfile.h ziphead.cpp \
21
+ ziphead.h flistscanner.ll
22
+
23
+ # test_flist_SOURCES = test_flist.cpp
24
+
25
+ test_izipfilt_SOURCES = test_izipfilt.cpp
26
+
27
+ test_izipstream_SOURCES = test_izipstream.cpp
28
+
29
+ test_zip_SOURCES = test_zip.cpp
30
+
31
+ # Notice that libzipios.a is not specified as -L. -lzipios
32
+ # If it was, automake would not include it as a dependency.
33
+
34
+ # test_flist_LDADD = libzipios.a
35
+
36
+ test_izipfilt_LDADD = libzipios.a -lz
37
+
38
+ test_zip_LDADD = libzipios.a -lz
39
+
40
+ test_izipstream_LDADD = libzipios.a -lz
41
+
42
+
43
+
44
+ flistscanner.cc : flistscanner.ll
45
+ $(LEX) -+ -PFListScanner -o$@ $^
46
+
@@ -0,0 +1,1504 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $VERBOSE = true
4
+
5
+ require 'rubyunit'
6
+ require 'zip'
7
+
8
+ include Zip
9
+
10
+ Dir.chdir "test"
11
+
12
+ class AbstractInputStreamTest < RUNIT::TestCase
13
+ # AbstractInputStream subclass that provides a read method
14
+
15
+ TEST_LINES = [ "Hello world#{$/}",
16
+ "this is the second line#{$/}",
17
+ "this is the last line"]
18
+ TEST_STRING = TEST_LINES.join
19
+ class TestAbstractInputStream
20
+ include AbstractInputStream
21
+ def initialize(aString)
22
+ @contents = aString
23
+ @readPointer = 0
24
+ end
25
+
26
+ def read(charsToRead)
27
+ retVal=@contents[@readPointer, charsToRead]
28
+ @readPointer+=charsToRead
29
+ return retVal
30
+ end
31
+
32
+ def produceInput
33
+ read(100)
34
+ end
35
+
36
+ def inputFinished?
37
+ @contents[@readPointer] == nil
38
+ end
39
+ end
40
+
41
+ def setup
42
+ @io = TestAbstractInputStream.new(TEST_STRING)
43
+ end
44
+
45
+ def test_gets
46
+ assert_equals(TEST_LINES[0], @io.gets)
47
+ assert_equals(TEST_LINES[1], @io.gets)
48
+ assert_equals(TEST_LINES[2], @io.gets)
49
+ assert_equals(nil, @io.gets)
50
+ end
51
+
52
+ def test_getsMultiCharSeperator
53
+ assert_equals("Hell", @io.gets("ll"))
54
+ assert_equals("o world#{$/}this is the second l", @io.gets("d l"))
55
+ end
56
+
57
+ def test_each_line
58
+ lineNumber=0
59
+ @io.each_line {
60
+ |line|
61
+ assert_equals(TEST_LINES[lineNumber], line)
62
+ lineNumber+=1
63
+ }
64
+ end
65
+
66
+ def test_readlines
67
+ assert_equals(TEST_LINES, @io.readlines)
68
+ end
69
+
70
+ def test_readline
71
+ test_gets
72
+ begin
73
+ @io.readline
74
+ fail "EOFError expected"
75
+ rescue EOFError
76
+ end
77
+ end
78
+ end
79
+
80
+ class ZipEntryTest < RUNIT::TestCase
81
+ TEST_ZIPFILE = "someZipFile.zip"
82
+ TEST_COMMENT = "a comment"
83
+ TEST_COMPRESSED_SIZE = 1234
84
+ TEST_CRC = 325324
85
+ TEST_EXTRA = "Some data here"
86
+ TEST_COMPRESSIONMETHOD = ZipEntry::DEFLATED
87
+ TEST_NAME = "entry name"
88
+ TEST_SIZE = 8432
89
+ TEST_ISDIRECTORY = false
90
+
91
+ def test_constructorAndGetters
92
+ entry = ZipEntry.new(TEST_ZIPFILE,
93
+ TEST_NAME,
94
+ TEST_COMMENT,
95
+ TEST_EXTRA,
96
+ TEST_COMPRESSED_SIZE,
97
+ TEST_CRC,
98
+ TEST_COMPRESSIONMETHOD,
99
+ TEST_SIZE)
100
+
101
+ assert_equals(TEST_COMMENT, entry.comment)
102
+ assert_equals(TEST_COMPRESSED_SIZE, entry.compressedSize)
103
+ assert_equals(TEST_CRC, entry.crc)
104
+ assert_equals(TEST_EXTRA, entry.extra)
105
+ assert_equals(TEST_COMPRESSIONMETHOD, entry.compressionMethod)
106
+ assert_equals(TEST_NAME, entry.name)
107
+ assert_equals(TEST_SIZE, entry.size)
108
+ assert_equals(TEST_ISDIRECTORY, entry.isDirectory)
109
+ end
110
+
111
+ def test_equality
112
+ entry1 = ZipEntry.new("file.zip", "name", "isNotCompared",
113
+ "something extra", 123, 1234,
114
+ ZipEntry::DEFLATED, 10000)
115
+ entry2 = ZipEntry.new("file.zip", "name", "isNotComparedXXX",
116
+ "something extra", 123, 1234,
117
+ ZipEntry::DEFLATED, 10000)
118
+ entry3 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
119
+ "something extra", 123, 1234,
120
+ ZipEntry::DEFLATED, 10000)
121
+ entry4 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
122
+ "something extraXX", 123, 1234,
123
+ ZipEntry::DEFLATED, 10000)
124
+ entry5 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
125
+ "something extraXX", 12, 1234,
126
+ ZipEntry::DEFLATED, 10000)
127
+ entry6 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
128
+ "something extraXX", 12, 123,
129
+ ZipEntry::DEFLATED, 10000)
130
+ entry7 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
131
+ "something extraXX", 12, 123,
132
+ ZipEntry::STORED, 10000)
133
+ entry8 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
134
+ "something extraXX", 12, 123,
135
+ ZipEntry::STORED, 100000)
136
+
137
+ assert_equals(entry1, entry1)
138
+ assert_equals(entry1, entry2)
139
+
140
+ assert(entry2 != entry3)
141
+ assert(entry3 != entry4)
142
+ assert(entry4 != entry5)
143
+ assert(entry5 != entry6)
144
+ assert(entry6 != entry7)
145
+ assert(entry7 != entry8)
146
+
147
+ assert(entry7 != "hello")
148
+ assert(entry7 != 12)
149
+ end
150
+ end
151
+
152
+ module IOizeString
153
+ attr_reader :tell
154
+
155
+ def read(count = nil)
156
+ @tell ||= 0
157
+ count = size unless count
158
+ retVal = slice(@tell, count)
159
+ @tell += count
160
+ return retVal
161
+ end
162
+
163
+ def seek(index, offset)
164
+ @tell ||= 0
165
+ case offset
166
+ when IO::SEEK_END
167
+ newPos = size + index
168
+ when IO::SEEK_SET
169
+ newPos = index
170
+ when IO::SEEK_CUR
171
+ newPos = @tell + index
172
+ else
173
+ raise "Error in test method IOizeString::seek"
174
+ end
175
+ if (newPos < 0 || newPos >= size)
176
+ raise Errno::EINVAL
177
+ else
178
+ @tell=newPos
179
+ end
180
+ end
181
+
182
+ def reset
183
+ @tell = 0
184
+ end
185
+ end
186
+
187
+ class ZipLocalEntryTest < RUNIT::TestCase
188
+ def test_readLocalEntryHeaderOfFirstTestZipEntry
189
+ File.open(TestZipFile::TEST_ZIP3.zipName) {
190
+ |file|
191
+ entry = ZipEntry.readLocalEntry(file)
192
+
193
+ assert_equal("", entry.comment)
194
+ # Differs from windows and unix because of CR LF
195
+ # assert_equal(480, entry.compressedSize)
196
+ # assert_equal(0x2a27930f, entry.crc)
197
+ # extra field is 21 bytes long
198
+ # probably contains some unix attrutes or something
199
+ # disabled: assert_equal(nil, entry.extra)
200
+ assert_equal(ZipEntry::DEFLATED, entry.compressionMethod)
201
+ assert_equal(TestZipFile::TEST_ZIP3.entryNames[0], entry.name)
202
+ assert_equal(File.size(TestZipFile::TEST_ZIP3.entryNames[0]), entry.size)
203
+ assert(! entry.isDirectory)
204
+ }
205
+ end
206
+
207
+ def test_readLocalEntryFromNonZipFile
208
+ File.open("ziptest.rb") {
209
+ |file|
210
+ assert_equals(nil, ZipEntry.readLocalEntry(file))
211
+ }
212
+ end
213
+
214
+ def test_readLocalEntryFromTruncatedZipFile
215
+ zipFragment=""
216
+ File.open(TestZipFile::TEST_ZIP2.zipName) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
217
+ zipFragment.extend(IOizeString).reset
218
+ entry = ZipEntry.new
219
+ entry.readLocalEntry(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
+ writeToFile("localEntryHeader.bin", "centralEntryHeader.bin", entry)
229
+ entryReadLocal, entryReadCentral = readFromFile("localEntryHeader.bin", "centralEntryHeader.bin")
230
+ compareLocalEntryHeaders(entry, entryReadLocal)
231
+ compareCDirEntryHeaders(entry, entryReadCentral)
232
+ end
233
+
234
+ private
235
+ def compareLocalEntryHeaders(entry1, entry2)
236
+ assert_equals(entry1.compressedSize , entry2.compressedSize)
237
+ assert_equals(entry1.crc , entry2.crc)
238
+ assert_equals(entry1.extra , entry2.extra)
239
+ assert_equals(entry1.compressionMethod, entry2.compressionMethod)
240
+ assert_equals(entry1.name , entry2.name)
241
+ assert_equals(entry1.size , entry2.size)
242
+ assert_equals(entry1.localHeaderOffset, entry2.localHeaderOffset)
243
+ end
244
+
245
+ def compareCDirEntryHeaders(entry1, entry2)
246
+ compareLocalEntryHeaders(entry1, entry2)
247
+ assert_equals(entry1.comment, entry2.comment)
248
+ end
249
+
250
+ def writeToFile(localFileName, centralFileName, entry)
251
+ File.open(localFileName, "wb") { |f| entry.writeLocalEntry(f) }
252
+ File.open(centralFileName, "wb") { |f| entry.writeCDirEntry(f) }
253
+ end
254
+
255
+ def readFromFile(localFileName, centralFileName)
256
+ localEntry = nil
257
+ cdirEntry = nil
258
+ File.open(localFileName, "rb") { |f| localEntry = ZipEntry.readLocalEntry(f) }
259
+ File.open(centralFileName, "rb") { |f| cdirEntry = ZipEntry.readCDirEntry(f) }
260
+ return [localEntry, cdirEntry]
261
+ end
262
+ end
263
+
264
+
265
+ module DecompressorTests
266
+ # expects @refText and @decompressor
267
+
268
+ def test_readEverything
269
+ assert_equals(@refText, @decompressor.read)
270
+ end
271
+
272
+ def test_readInChunks
273
+ chunkSize = 5
274
+ while (decompressedChunk = @decompressor.read(chunkSize))
275
+ assert_equals(@refText.slice!(0, chunkSize), decompressedChunk)
276
+ end
277
+ assert_equals(0, @refText.size)
278
+ end
279
+ end
280
+
281
+ class InflaterTest < RUNIT::TestCase
282
+ include DecompressorTests
283
+
284
+ def setup
285
+ @file = File.new("file1.txt.deflatedData", "rb")
286
+ @refText=""
287
+ File.open("file1.txt") { |f| @refText = f.read }
288
+ @decompressor = Inflater.new(@file)
289
+ end
290
+
291
+ def teardown
292
+ @file.close
293
+ end
294
+ end
295
+
296
+
297
+ class PassThruDecompressorTest < RUNIT::TestCase
298
+ include DecompressorTests
299
+ TEST_FILE="file1.txt"
300
+ def setup
301
+ @file = File.new(TEST_FILE)
302
+ @refText=""
303
+ File.open(TEST_FILE) { |f| @refText = f.read }
304
+ @decompressor = PassThruDecompressor.new(@file, File.size(TEST_FILE))
305
+ end
306
+
307
+ def teardown
308
+ @file.close
309
+ end
310
+ end
311
+
312
+
313
+ module AssertEntry
314
+ def assertNextEntry(filename, zis)
315
+ assertEntry(filename, zis, zis.getNextEntry.name)
316
+ end
317
+
318
+ def assertEntry(filename, zis, entryName)
319
+ assert_equals(filename, entryName)
320
+ assertEntryContentsForStream(filename, zis, entryName)
321
+ end
322
+
323
+ def assertEntryContentsForStream(filename, zis, entryName)
324
+ File.open(filename, "rb") {
325
+ |file|
326
+ expected = file.read
327
+ actual = zis.read
328
+ if (expected != actual)
329
+ if (expected.length > 400 || actual.length > 400)
330
+ zipEntryFilename=entryName+".zipEntry"
331
+ File.open(zipEntryFilename, "wb") { |file| file << actual }
332
+ fail("File '#{filename}' is different from '#{zipEntryFilename}'")
333
+ else
334
+ assert_equals(expected, actual)
335
+ end
336
+ end
337
+ }
338
+ end
339
+
340
+ def AssertEntry.assertContents(filename, aString)
341
+ fileContents = ""
342
+ File.open(filename, "rb") { |f| fileContents = f.read }
343
+ if (fileContents != aString)
344
+ if (expected.length > 400 || actual.length > 400)
345
+ stringFile = filename + ".other"
346
+ File.open(stringFile, "wb") { |f| f << aString }
347
+ fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
348
+ else
349
+ assert_equals(expected, actual)
350
+ end
351
+ end
352
+ end
353
+
354
+ def assertStreamContents(zis, testZipFile)
355
+ assert(zis != nil)
356
+ testZipFile.entryNames.each {
357
+ |entryName|
358
+ assertNextEntry(entryName, zis)
359
+ }
360
+ assert_equals(nil, zis.getNextEntry)
361
+ end
362
+
363
+ def assertTestZipContents(testZipFile)
364
+ ZipInputStream.open(testZipFile.zipName) {
365
+ |zis|
366
+ assertStreamContents(zis, testZipFile)
367
+ }
368
+ end
369
+
370
+ def assertEntryContents(zipFile, entryName, filename = entryName.to_s)
371
+ zis = zipFile.getInputStream(entryName)
372
+ assertEntryContentsForStream(filename, zis, entryName)
373
+ ensure
374
+ zis.close if zis
375
+ end
376
+ end
377
+
378
+
379
+
380
+ class ZipInputStreamTest < RUNIT::TestCase
381
+ include AssertEntry
382
+
383
+ def test_new
384
+ zis = ZipInputStream.new(TestZipFile::TEST_ZIP2.zipName)
385
+ assertStreamContents(zis, TestZipFile::TEST_ZIP2)
386
+ zis.close
387
+ end
388
+
389
+ def test_openWithBlock
390
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName) {
391
+ |zis|
392
+ assertStreamContents(zis, TestZipFile::TEST_ZIP2)
393
+ }
394
+ end
395
+
396
+ def test_openWithoutBlock
397
+ zis = ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName)
398
+ assertStreamContents(zis, TestZipFile::TEST_ZIP2)
399
+ end
400
+
401
+ def test_incompleteReads
402
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName) {
403
+ |zis|
404
+ entry = zis.getNextEntry
405
+ assert_equals(TestZipFile::TEST_ZIP2.entryNames[0], entry.name)
406
+ assert zis.gets.length > 0
407
+ entry = zis.getNextEntry
408
+ assert_equals(TestZipFile::TEST_ZIP2.entryNames[1], entry.name)
409
+ assert_equals(0, entry.size)
410
+ assert_equals(nil, zis.gets)
411
+ entry = zis.getNextEntry
412
+ assert_equals(TestZipFile::TEST_ZIP2.entryNames[2], entry.name)
413
+ assert zis.gets.length > 0
414
+ entry = zis.getNextEntry
415
+ assert_equals(TestZipFile::TEST_ZIP2.entryNames[3], entry.name)
416
+ assert zis.gets.length > 0
417
+ }
418
+ end
419
+
420
+ end
421
+
422
+ class TestFiles
423
+ RANDOM_ASCII_FILE1 = "randomAscii1.txt"
424
+ RANDOM_ASCII_FILE2 = "randomAscii2.txt"
425
+ RANDOM_ASCII_FILE3 = "randomAscii3.txt"
426
+ RANDOM_BINARY_FILE1 = "randomBinary1.bin"
427
+ RANDOM_BINARY_FILE2 = "randomBinary2.bin"
428
+
429
+ EMPTY_TEST_DIR = "emptytestdir"
430
+
431
+ ASCII_TEST_FILES = [ RANDOM_ASCII_FILE1, RANDOM_ASCII_FILE2, RANDOM_ASCII_FILE3 ]
432
+ BINARY_TEST_FILES = [ RANDOM_BINARY_FILE1, RANDOM_BINARY_FILE2 ]
433
+ TEST_DIRECTORIES = [ EMPTY_TEST_DIR ]
434
+ TEST_FILES = [ ASCII_TEST_FILES, BINARY_TEST_FILES, EMPTY_TEST_DIR ].flatten!
435
+
436
+ def TestFiles.createTestFiles(recreate)
437
+ if (recreate ||
438
+ ! (TEST_FILES.inject(true) { |accum, element| accum && File.exists?(element) }))
439
+
440
+ ASCII_TEST_FILES.each_with_index {
441
+ |filename, index|
442
+ createRandomAscii(filename, 1E4 * (index+1))
443
+ }
444
+
445
+ BINARY_TEST_FILES.each_with_index {
446
+ |filename, index|
447
+ createRandomBinary(filename, 1E4 * (index+1))
448
+ }
449
+
450
+ ensureDir(EMPTY_TEST_DIR)
451
+ end
452
+ end
453
+
454
+ private
455
+ def TestFiles.createRandomAscii(filename, size)
456
+ File.open(filename, "wb") {
457
+ |file|
458
+ while (file.tell < size)
459
+ file << rand
460
+ end
461
+ }
462
+ end
463
+
464
+ def TestFiles.createRandomBinary(filename, size)
465
+ File.open(filename, "wb") {
466
+ |file|
467
+ while (file.tell < size)
468
+ file << rand.to_a.pack("V")
469
+ end
470
+ }
471
+ end
472
+
473
+ def TestFiles.ensureDir(name)
474
+ if File.exists?(name)
475
+ return if File.stat(name).directory?
476
+ File.delete(name)
477
+ end
478
+ Dir.mkdir(name)
479
+ end
480
+
481
+ end
482
+
483
+ # For representation and creation of
484
+ # test data
485
+ class TestZipFile
486
+ attr_accessor :zipName, :entryNames, :comment
487
+
488
+ def initialize(zipName, entryNames, comment = "")
489
+ @zipName=zipName
490
+ @entryNames=entryNames
491
+ @comment = comment
492
+ end
493
+
494
+ def TestZipFile.createTestZips(recreate)
495
+ files = Dir.entries(".")
496
+ if (recreate ||
497
+ ! (files.index(TEST_ZIP1.zipName) &&
498
+ files.index(TEST_ZIP2.zipName) &&
499
+ files.index(TEST_ZIP3.zipName) &&
500
+ files.index(TEST_ZIP4.zipName) &&
501
+ files.index("empty.txt") &&
502
+ files.index("short.txt") &&
503
+ files.index("longAscii.txt") &&
504
+ files.index("longBinary.bin") ))
505
+ raise "failed to create test zip '#{TEST_ZIP1.zipName}'" unless
506
+ system("zip #{TEST_ZIP1.zipName} ziptest.rb")
507
+ raise "failed to remove entry from '#{TEST_ZIP1.zipName}'" unless
508
+ system("zip #{TEST_ZIP1.zipName} -d ziptest.rb")
509
+
510
+ File.open("empty.txt", "w") {}
511
+
512
+ File.open("short.txt", "w") { |file| file << "ABCDEF" }
513
+ ziptestTxt=""
514
+ File.open("ziptest.rb") { |file| ziptestTxt=file.read }
515
+ File.open("longAscii.txt", "w") {
516
+ |file|
517
+ while (file.tell < 1E5)
518
+ file << ziptestTxt
519
+ end
520
+ }
521
+
522
+ testBinaryPattern=""
523
+ File.open("empty.zip") { |file| testBinaryPattern=file.read }
524
+ testBinaryPattern *= 4
525
+
526
+ File.open("longBinary.bin", "wb") {
527
+ |file|
528
+ while (file.tell < 3E5)
529
+ file << testBinaryPattern << rand
530
+ end
531
+ }
532
+ raise "failed to create test zip '#{TEST_ZIP2.zipName}'" unless
533
+ system("zip #{TEST_ZIP2.zipName} #{TEST_ZIP2.entryNames.join(' ')}")
534
+
535
+ # without bash system interprets everything after echo as parameters to
536
+ # echo including | zip -z ...
537
+ raise "failed to add comment to test zip '#{TEST_ZIP2.zipName}'" unless
538
+ system("bash -c \"echo #{TEST_ZIP2.comment} | zip -z #{TEST_ZIP2.zipName}\"")
539
+
540
+ raise "failed to create test zip '#{TEST_ZIP3.zipName}'" unless
541
+ system("zip #{TEST_ZIP3.zipName} #{TEST_ZIP3.entryNames.join(' ')}")
542
+
543
+ raise "failed to create test zip '#{TEST_ZIP4.zipName}'" unless
544
+ system("zip #{TEST_ZIP4.zipName} #{TEST_ZIP4.entryNames.join(' ')}")
545
+ end
546
+ rescue
547
+ raise $!.to_s +
548
+ "\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" +
549
+ "to create test data. If you don't have it you can download\n" +
550
+ "the necessary test files at http://sf.net/projects/rubyzip."
551
+ end
552
+
553
+ TEST_ZIP1 = TestZipFile.new("empty.zip", [])
554
+ TEST_ZIP2 = TestZipFile.new("4entry.zip", %w{ longAscii.txt empty.txt short.txt longBinary.bin},
555
+ "my zip comment")
556
+ TEST_ZIP3 = TestZipFile.new("test1.zip", %w{ file1.txt })
557
+ TEST_ZIP4 = TestZipFile.new("zipWithDir.zip", [ "file1.txt",
558
+ TestFiles::EMPTY_TEST_DIR])
559
+ end
560
+
561
+
562
+ class AbstractOutputStreamTest < RUNIT::TestCase
563
+ class TestOutputStream
564
+ include AbstractOutputStream
565
+
566
+ attr_accessor :buffer
567
+
568
+ def initialize
569
+ @buffer = ""
570
+ end
571
+
572
+ def << (data)
573
+ @buffer << data
574
+ self
575
+ end
576
+ end
577
+
578
+ def setup
579
+ @outputStream = TestOutputStream.new
580
+
581
+ @origCommaSep = $,
582
+ @origOutputSep = $\
583
+ end
584
+
585
+ def teardown
586
+ $, = @origCommaSep
587
+ $\ = @origOutputSep
588
+ end
589
+
590
+ def test_write
591
+ count = @outputStream.write("a little string")
592
+ assert_equals("a little string", @outputStream.buffer)
593
+ assert_equals("a little string".length, count)
594
+
595
+ count = @outputStream.write(". a little more")
596
+ assert_equals("a little string. a little more", @outputStream.buffer)
597
+ assert_equals(". a little more".length, count)
598
+ end
599
+
600
+ def test_print
601
+ $\ = nil # record separator set to nil
602
+ @outputStream.print("hello")
603
+ assert_equals("hello", @outputStream.buffer)
604
+
605
+ @outputStream.print(" world.")
606
+ assert_equals("hello world.", @outputStream.buffer)
607
+
608
+ @outputStream.print(" You ok ", "out ", "there?")
609
+ assert_equals("hello world. You ok out there?", @outputStream.buffer)
610
+
611
+ $\ = "\n"
612
+ @outputStream.print
613
+ assert_equals("hello world. You ok out there?\n", @outputStream.buffer)
614
+
615
+ @outputStream.print("I sure hope so!")
616
+ assert_equals("hello world. You ok out there?\nI sure hope so!\n", @outputStream.buffer)
617
+
618
+ $, = "X"
619
+ @outputStream.buffer = ""
620
+ @outputStream.print("monkey", "duck", "zebra")
621
+ assert_equals("monkeyXduckXzebra\n", @outputStream.buffer)
622
+
623
+ $\ = nil
624
+ @outputStream.buffer = ""
625
+ @outputStream.print(20)
626
+ assert_equals("20", @outputStream.buffer)
627
+ end
628
+
629
+ def test_printf
630
+ @outputStream.printf("%d %04x", 123, 123)
631
+ assert_equals("123 007b", @outputStream.buffer)
632
+ end
633
+
634
+ def test_putc
635
+ @outputStream.putc("A")
636
+ assert_equals("A", @outputStream.buffer)
637
+ @outputStream.putc(65)
638
+ assert_equals("AA", @outputStream.buffer)
639
+ end
640
+
641
+ def test_puts
642
+ @outputStream.puts
643
+ assert_equals("\n", @outputStream.buffer)
644
+
645
+ @outputStream.puts("hello", "world")
646
+ assert_equals("\nhello\nworld\n", @outputStream.buffer)
647
+
648
+ @outputStream.buffer = ""
649
+ @outputStream.puts("hello\n", "world\n")
650
+ assert_equals("hello\nworld\n", @outputStream.buffer)
651
+
652
+ @outputStream.buffer = ""
653
+ @outputStream.puts(["hello\n", "world\n"])
654
+ assert_equals("hello\nworld\n", @outputStream.buffer)
655
+
656
+ @outputStream.buffer = ""
657
+ @outputStream.puts(["hello\n", "world\n"], "bingo")
658
+ assert_equals("hello\nworld\nbingo\n", @outputStream.buffer)
659
+
660
+ @outputStream.buffer = ""
661
+ @outputStream.puts(16, 20, 50, "hello")
662
+ assert_equals("16\n20\n50\nhello\n", @outputStream.buffer)
663
+ end
664
+ end
665
+
666
+
667
+ module CrcTest
668
+ def runCrcTest(compressorClass)
669
+ str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
670
+ fakeOut = AbstractOutputStreamTest::TestOutputStream.new
671
+
672
+ deflater = compressorClass.new(fakeOut)
673
+ deflater << str
674
+ assert_equals(0x919920fc, deflater.crc)
675
+ end
676
+ end
677
+
678
+
679
+
680
+ class PassThruCompressorTest < RUNIT::TestCase
681
+ include CrcTest
682
+
683
+ def test_size
684
+ File.open("dummy.txt", "wb") {
685
+ |file|
686
+ compressor = PassThruCompressor.new(file)
687
+
688
+ assert_equals(0, compressor.size)
689
+
690
+ t1 = "hello world"
691
+ t2 = ""
692
+ t3 = "bingo"
693
+
694
+ compressor << t1
695
+ assert_equals(compressor.size, t1.size)
696
+
697
+ compressor << t2
698
+ assert_equals(compressor.size, t1.size + t2.size)
699
+
700
+ compressor << t3
701
+ assert_equals(compressor.size, t1.size + t2.size + t3.size)
702
+ }
703
+ end
704
+
705
+ def test_crc
706
+ runCrcTest(PassThruCompressor)
707
+ end
708
+ end
709
+
710
+ class DeflaterTest < RUNIT::TestCase
711
+ include CrcTest
712
+
713
+ def test_outputOperator
714
+ txt = loadFile("ziptest.rb")
715
+ deflate(txt, "deflatertest.bin")
716
+ inflatedTxt = inflate("deflatertest.bin")
717
+ assert_equals(txt, inflatedTxt)
718
+ end
719
+
720
+ private
721
+ def loadFile(fileName)
722
+ txt = nil
723
+ File.open(fileName, "rb") { |f| txt = f.read }
724
+ end
725
+
726
+ def deflate(data, fileName)
727
+ File.open(fileName, "wb") {
728
+ |file|
729
+ deflater = Deflater.new(file)
730
+ deflater << data
731
+ deflater.finish
732
+ assert_equals(deflater.size, data.size)
733
+ file << "trailing data for zlib with -MAX_WBITS"
734
+ }
735
+ end
736
+
737
+ def inflate(fileName)
738
+ txt = nil
739
+ File.open(fileName, "rb") {
740
+ |file|
741
+ inflater = Inflater.new(file)
742
+ txt = inflater.read
743
+ }
744
+ end
745
+
746
+ def test_crc
747
+ runCrcTest(Deflater)
748
+ end
749
+ end
750
+
751
+ class ZipOutputStreamTest < RUNIT::TestCase
752
+ include AssertEntry
753
+
754
+ TEST_ZIP = TestZipFile::TEST_ZIP2.clone
755
+ TEST_ZIP.zipName = "output.zip"
756
+
757
+ def test_new
758
+ zos = ZipOutputStream.new(TEST_ZIP.zipName)
759
+ zos.comment = TEST_ZIP.comment
760
+ writeTestZip(zos)
761
+ zos.close
762
+ assertTestZipContents(TEST_ZIP)
763
+ end
764
+
765
+ def test_open
766
+ ZipOutputStream.open(TEST_ZIP.zipName) {
767
+ |zos|
768
+ zos.comment = TEST_ZIP.comment
769
+ writeTestZip(zos)
770
+ }
771
+ assertTestZipContents(TEST_ZIP)
772
+ end
773
+
774
+ def test_writingToClosedStream
775
+ assertIOErrorInClosedStream { |zos| zos << "hello world" }
776
+ assertIOErrorInClosedStream { |zos| zos.puts "hello world" }
777
+ assertIOErrorInClosedStream { |zos| zos.write "hello world" }
778
+ end
779
+
780
+ def test_cannotOpenFile
781
+ name = TestFiles::EMPTY_TEST_DIR
782
+ begin
783
+ zos = ZipOutputStream.open(name)
784
+ rescue Exception
785
+ assert($!.kind_of?(Errno::EISDIR) || # Linux
786
+ $!.kind_of?(Errno::EEXIST) || # Windows/cygwin
787
+ $!.kind_of?(Errno::EACCES), # Windows
788
+ "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.type}")
789
+ end
790
+ end
791
+
792
+ def assertIOErrorInClosedStream
793
+ assert_exception(IOError) {
794
+ zos = ZipOutputStream.new("test_putOnClosedStream.zip")
795
+ zos.close
796
+ yield zos
797
+ }
798
+ end
799
+
800
+ def writeTestZip(zos)
801
+ TEST_ZIP.entryNames.each {
802
+ |entryName|
803
+ zos.putNextEntry(entryName)
804
+ File.open(entryName, "rb") { |f| zos.write(f.read) }
805
+ }
806
+ end
807
+ end
808
+
809
+
810
+
811
+ module Enumerable
812
+ def compareEnumerables(otherEnumerable)
813
+ otherAsArray = otherEnumerable.to_a
814
+ index=0
815
+ each_with_index {
816
+ |element, index|
817
+ return false unless yield(element, otherAsArray[index])
818
+ }
819
+ return index+1 == otherAsArray.size
820
+ end
821
+ end
822
+
823
+
824
+ class ZipCentralDirectoryEntryTest < RUNIT::TestCase
825
+
826
+ def test_readFromStream
827
+ File.open("testDirectory.bin", "rb") {
828
+ |file|
829
+ entry = ZipEntry.readCDirEntry(file)
830
+
831
+ assert_equals("longAscii.txt", entry.name)
832
+ assert_equals(ZipEntry::DEFLATED, entry.compressionMethod)
833
+ assert_equals(106490, entry.size)
834
+ assert_equals(3784, entry.compressedSize)
835
+ assert_equals(0xfcd1799c, entry.crc)
836
+ assert_equals("", entry.comment)
837
+
838
+ entry = ZipEntry.readCDirEntry(file)
839
+ assert_equals("empty.txt", entry.name)
840
+ assert_equals(ZipEntry::STORED, entry.compressionMethod)
841
+ assert_equals(0, entry.size)
842
+ assert_equals(0, entry.compressedSize)
843
+ assert_equals(0x0, entry.crc)
844
+ assert_equals("", entry.comment)
845
+
846
+ entry = ZipEntry.readCDirEntry(file)
847
+ assert_equals("short.txt", entry.name)
848
+ assert_equals(ZipEntry::STORED, entry.compressionMethod)
849
+ assert_equals(6, entry.size)
850
+ assert_equals(6, entry.compressedSize)
851
+ assert_equals(0xbb76fe69, entry.crc)
852
+ assert_equals("", entry.comment)
853
+
854
+ entry = ZipEntry.readCDirEntry(file)
855
+ assert_equals("longBinary.bin", entry.name)
856
+ assert_equals(ZipEntry::DEFLATED, entry.compressionMethod)
857
+ assert_equals(1000024, entry.size)
858
+ assert_equals(70847, entry.compressedSize)
859
+ assert_equals(0x10da7d59, entry.crc)
860
+ assert_equals("", entry.comment)
861
+
862
+ entry = ZipEntry.readCDirEntry(file)
863
+ assert_equals(nil, entry)
864
+ # Fields that are not check by this test:
865
+ # version made by 2 bytes
866
+ # version needed to extract 2 bytes
867
+ # general purpose bit flag 2 bytes
868
+ # last mod file time 2 bytes
869
+ # last mod file date 2 bytes
870
+ # compressed size 4 bytes
871
+ # uncompressed size 4 bytes
872
+ # disk number start 2 bytes
873
+ # internal file attributes 2 bytes
874
+ # external file attributes 4 bytes
875
+ # relative offset of local header 4 bytes
876
+
877
+ # file name (variable size)
878
+ # extra field (variable size)
879
+ # file comment (variable size)
880
+
881
+ }
882
+ end
883
+
884
+ def test_ReadEntryFromTruncatedZipFile
885
+ fragment=""
886
+ File.open("testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
887
+ fragment.extend(IOizeString)
888
+ entry = ZipEntry.new
889
+ entry.readCDirEntry(fragment)
890
+ fail "ZipError expected"
891
+ rescue ZipError
892
+ end
893
+
894
+ end
895
+
896
+ class ZipCentralDirectoryTest < RUNIT::TestCase
897
+
898
+ def test_readFromStream
899
+ File.open(TestZipFile::TEST_ZIP2.zipName, "rb") {
900
+ |zipFile|
901
+ cdir = ZipCentralDirectory.readFromStream(zipFile)
902
+
903
+ assert_equals(TestZipFile::TEST_ZIP2.entryNames.size, cdir.size)
904
+ assert(cdir.compareEnumerables(TestZipFile::TEST_ZIP2.entryNames) {
905
+ |cdirEntry, testEntryName|
906
+ cdirEntry.name == testEntryName
907
+ })
908
+ assert_equals(TestZipFile::TEST_ZIP2.comment, cdir.comment)
909
+ }
910
+ end
911
+
912
+ def test_readFromInvalidStream
913
+ File.open("ziptest.rb", "rb") {
914
+ |zipFile|
915
+ cdir = ZipCentralDirectory.new
916
+ cdir.readFromStream(zipFile)
917
+ }
918
+ fail "ZipError expected!"
919
+ rescue ZipError
920
+ end
921
+
922
+ def test_ReadFromTruncatedZipFile
923
+ fragment=""
924
+ File.open("testDirectory.bin") { |f| fragment = f.read }
925
+ fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
926
+ fragment.extend(IOizeString)
927
+ entry = ZipCentralDirectory.new
928
+ entry.readFromStream(fragment)
929
+ fail "ZipError expected"
930
+ rescue ZipError
931
+ end
932
+
933
+ def test_writeToStream
934
+ entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
935
+ ZipEntry.new("file.zip", "secondEntryName"),
936
+ ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
937
+ cdir = ZipCentralDirectory.new(entries, "my zip comment")
938
+ File.open("cdirtest.bin", "wb") { |f| cdir.writeToStream(f) }
939
+ cdirReadback = ZipCentralDirectory.new
940
+ File.open("cdirtest.bin", "rb") { |f| cdirReadback.readFromStream(f) }
941
+
942
+ assert_equals(cdir.entries, cdirReadback.entries)
943
+ end
944
+
945
+ def test_equality
946
+ cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
947
+ "somethingExtra"),
948
+ ZipEntry.new("file.zip", "secondEntryName"),
949
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
950
+ "my zip comment")
951
+ cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
952
+ "somethingExtra"),
953
+ ZipEntry.new("file.zip", "secondEntryName"),
954
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
955
+ "my zip comment")
956
+ cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
957
+ "somethingExtra"),
958
+ ZipEntry.new("file.zip", "secondEntryName"),
959
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
960
+ "comment?")
961
+ cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
962
+ "somethingExtra"),
963
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
964
+ "comment?")
965
+ assert_equals(cdir1, cdir1)
966
+ assert_equals(cdir1, cdir2)
967
+
968
+ assert(cdir1 != cdir3)
969
+ assert(cdir2 != cdir3)
970
+ assert(cdir2 != cdir3)
971
+ assert(cdir3 != cdir4)
972
+
973
+ assert(cdir3 != "hello")
974
+ end
975
+ end
976
+
977
+
978
+ class BasicZipFileTest < RUNIT::TestCase
979
+ include AssertEntry
980
+
981
+ def setup
982
+ @zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zipName)
983
+ @testEntryNameIndex=0
984
+ end
985
+
986
+ def nextTestEntryName
987
+ retVal=TestZipFile::TEST_ZIP2.entryNames[@testEntryNameIndex]
988
+ @testEntryNameIndex+=1
989
+ return retVal
990
+ end
991
+
992
+ def test_entries
993
+ assert_equals(TestZipFile::TEST_ZIP2.entryNames, @zipFile.entries.map {|e| e.name} )
994
+ end
995
+
996
+ def test_each
997
+ @zipFile.each {
998
+ |entry|
999
+ assert_equals(nextTestEntryName, entry.name)
1000
+ }
1001
+ assert_equals(4, @testEntryNameIndex)
1002
+ end
1003
+
1004
+ def test_foreach
1005
+ ZipFile.foreach(TestZipFile::TEST_ZIP2.zipName) {
1006
+ |entry|
1007
+ assert_equals(nextTestEntryName, entry.name)
1008
+ }
1009
+ assert_equals(4, @testEntryNameIndex)
1010
+ end
1011
+
1012
+ def test_getInputStream
1013
+ @zipFile.each {
1014
+ |entry|
1015
+ assertEntry(nextTestEntryName, @zipFile.getInputStream(entry),
1016
+ entry.name)
1017
+ }
1018
+ assert_equals(4, @testEntryNameIndex)
1019
+ end
1020
+
1021
+ def test_getInputStreamBlock
1022
+ fileAndEntryName = @zipFile.entries.first.name
1023
+ @zipFile.getInputStream(fileAndEntryName) {
1024
+ |zis|
1025
+ assertEntryContentsForStream(fileAndEntryName,
1026
+ zis,
1027
+ fileAndEntryName)
1028
+ }
1029
+ end
1030
+ end
1031
+
1032
+ class CommonZipFileFixture < RUNIT::TestCase
1033
+ include AssertEntry
1034
+
1035
+ EMPTY_FILENAME = "emptyZipFile.zip"
1036
+
1037
+ TEST_ZIP = TestZipFile::TEST_ZIP2.clone
1038
+ TEST_ZIP.zipName = "4entry_copy.zip"
1039
+
1040
+ def setup
1041
+ File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
1042
+ File.copy(TestZipFile::TEST_ZIP2.zipName, TEST_ZIP.zipName)
1043
+ end
1044
+ end
1045
+
1046
+ class ZipFileTest < CommonZipFileFixture
1047
+
1048
+ def test_createFromScratch
1049
+ comment = "a short comment"
1050
+
1051
+ zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1052
+ zf.comment = comment
1053
+ zf.close
1054
+
1055
+ zfRead = ZipFile.new(EMPTY_FILENAME)
1056
+ assert_equals(comment, zfRead.comment)
1057
+ assert_equals(0, zfRead.entries.length)
1058
+ end
1059
+
1060
+ def test_add
1061
+ srcFile = "ziptest.rb"
1062
+ entryName = "newEntryName.rb"
1063
+ assert(File.exists? srcFile)
1064
+ zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1065
+ zf.add(entryName, srcFile)
1066
+ zf.close
1067
+
1068
+ zfRead = ZipFile.new(EMPTY_FILENAME)
1069
+ assert_equals("", zfRead.comment)
1070
+ assert_equals(1, zfRead.entries.length)
1071
+ assert_equals(entryName, zfRead.entries.first.name)
1072
+ AssertEntry.assertContents(srcFile,
1073
+ zfRead.getInputStream(entryName) { |zis| zis.read })
1074
+ end
1075
+
1076
+ def test_addExistingEntryName
1077
+ assert_exception(ZipEntryExistsError) {
1078
+ ZipFile.open(TEST_ZIP.zipName) {
1079
+ |zf|
1080
+ zf.add(zf.entries.first.name, "ziptest.rb")
1081
+ }
1082
+ }
1083
+ end
1084
+
1085
+ def test_addExistingEntryNameReplace
1086
+ gotCalled = false
1087
+ replacedEntry = nil
1088
+ ZipFile.open(TEST_ZIP.zipName) {
1089
+ |zf|
1090
+ replacedEntry = zf.entries.first.name
1091
+ zf.add(replacedEntry, "ziptest.rb") { gotCalled = true; true }
1092
+ }
1093
+ assert(gotCalled)
1094
+ ZipFile.open(TEST_ZIP.zipName) {
1095
+ |zf|
1096
+ assertContains(zf, replacedEntry, "ziptest.rb")
1097
+ }
1098
+ end
1099
+
1100
+ def test_addDirectory
1101
+ ZipFile.open(TEST_ZIP.zipName) {
1102
+ |zf|
1103
+ zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
1104
+ }
1105
+ ZipFile.open(TEST_ZIP.zipName) {
1106
+ |zf|
1107
+ dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
1108
+ assert(dirEntry.isDirectory)
1109
+ }
1110
+ end
1111
+
1112
+ def test_remove
1113
+ entryToRemove, *remainingEntries = TEST_ZIP.entryNames
1114
+
1115
+ File.copy(TestZipFile::TEST_ZIP2.zipName, TEST_ZIP.zipName)
1116
+
1117
+ zf = ZipFile.new(TEST_ZIP.zipName)
1118
+ assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
1119
+ zf.remove(entryToRemove)
1120
+ assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
1121
+ assert_equals(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
1122
+ zf.close
1123
+
1124
+ zfRead = ZipFile.new(TEST_ZIP.zipName)
1125
+ assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
1126
+ assert_equals(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
1127
+ zfRead.close
1128
+ end
1129
+
1130
+
1131
+ def test_rename
1132
+ entryToRename, *remainingEntries = TEST_ZIP.entryNames
1133
+
1134
+ zf = ZipFile.new(TEST_ZIP.zipName)
1135
+ assert(zf.entries.map { |e| e.name }.include? entryToRename)
1136
+
1137
+ newName = "changed name"
1138
+ assert(! zf.entries.map { |e| e.name }.include?(newName))
1139
+
1140
+ zf.rename(entryToRename, newName)
1141
+ assert(zf.entries.map { |e| e.name }.include? newName)
1142
+
1143
+ zf.close
1144
+
1145
+ zfRead = ZipFile.new(TEST_ZIP.zipName)
1146
+ assert(zfRead.entries.map { |e| e.name }.include? newName)
1147
+ zfRead.close
1148
+ end
1149
+
1150
+ def test_renameToExistingEntry
1151
+ oldEntries = nil
1152
+ ZipFile.open(TEST_ZIP.zipName) { |zf| oldEntries = zf.entries }
1153
+
1154
+ assert_exception(ZipEntryExistsError) {
1155
+ ZipFile.open(TEST_ZIP.zipName) {
1156
+ |zf|
1157
+ zf.rename(zf.entries[0], zf.entries[1].name)
1158
+ }
1159
+ }
1160
+
1161
+ ZipFile.open(TEST_ZIP.zipName) {
1162
+ |zf|
1163
+ assert_equals(oldEntries.map{ |e| e.name }, zf.entries.map{ |e| e.name })
1164
+ }
1165
+ end
1166
+
1167
+ def test_renameToExistingEntryOverwrite
1168
+ oldEntries = nil
1169
+ ZipFile.open(TEST_ZIP.zipName) { |zf| oldEntries = zf.entries }
1170
+
1171
+ gotCalled = false
1172
+ ZipFile.open(TEST_ZIP.zipName) {
1173
+ |zf|
1174
+ zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
1175
+ }
1176
+
1177
+ assert(gotCalled)
1178
+ oldEntries.delete_at(0)
1179
+ ZipFile.open(TEST_ZIP.zipName) {
1180
+ |zf|
1181
+ assert_equals(oldEntries.map{ |e| e.name },
1182
+ zf.entries.map{ |e| e.name })
1183
+ }
1184
+ end
1185
+
1186
+ def test_renameNonEntry
1187
+ nonEntry = "bogusEntry"
1188
+ targetEntry = "targetEntryName"
1189
+ zf = ZipFile.new(TEST_ZIP.zipName)
1190
+ assert(! zf.entries.include?(nonEntry))
1191
+ assert_exception(ZipNoSuchEntryError) {
1192
+ zf.rename(nonEntry, targetEntry)
1193
+ }
1194
+ zf.commit
1195
+ assert(! zf.entries.include?(targetEntry))
1196
+ ensure
1197
+ zf.close
1198
+ end
1199
+
1200
+ def test_renameEntryToExistingEntry
1201
+ entry1, entry2, *remaining = TEST_ZIP.entryNames
1202
+ zf = ZipFile.new(TEST_ZIP.zipName)
1203
+ assert_exception(ZipEntryExistsError) {
1204
+ zf.rename(entry1, entry2)
1205
+ }
1206
+ ensure
1207
+ zf.close
1208
+ end
1209
+
1210
+ def test_replace
1211
+ unchangedEntries = TEST_ZIP.entryNames.dup
1212
+ entryToReplace = unchangedEntries.delete_at(2)
1213
+ newEntrySrcFilename = "ziptest.rb"
1214
+
1215
+ zf = ZipFile.new(TEST_ZIP.zipName)
1216
+ zf.replace(entryToReplace, newEntrySrcFilename)
1217
+
1218
+ zf.close
1219
+
1220
+ zfRead = ZipFile.new(TEST_ZIP.zipName)
1221
+ AssertEntry::assertContents(newEntrySrcFilename,
1222
+ zfRead.getInputStream(entryToReplace) { |is| is.read })
1223
+ zfRead.close
1224
+ end
1225
+
1226
+ def test_replaceNonEntry
1227
+ entryToReplace = "nonExistingEntryname"
1228
+ ZipFile.open(TEST_ZIP.zipName) {
1229
+ |zf|
1230
+ assert_exception(ZipNoSuchEntryError) {
1231
+ zf.replace(entryToReplace, "ziptest.rb")
1232
+ }
1233
+ }
1234
+ end
1235
+
1236
+ def test_commit
1237
+ newName = "renamedFirst"
1238
+ zf = ZipFile.new(TEST_ZIP.zipName)
1239
+ oldName = zf.entries.first
1240
+ zf.rename(oldName, newName)
1241
+ zf.commit
1242
+
1243
+ zfRead = ZipFile.new(TEST_ZIP.zipName)
1244
+ assert(zfRead.entries.detect { |e| e.name == newName } != nil)
1245
+ assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
1246
+ zfRead.close
1247
+
1248
+ zf.close
1249
+ end
1250
+
1251
+ # This test tests that after commit, you
1252
+ # can delete the file you used to add the entry to the zip file
1253
+ # with
1254
+ def test_commitUseZipEntry
1255
+ File.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
1256
+ zf = ZipFile.open(TEST_ZIP.zipName)
1257
+ zf.add("okToDelete.txt", "okToDelete.txt")
1258
+ assertContains(zf, "okToDelete.txt")
1259
+ zf.commit
1260
+ File.move("okToDelete.txt", "okToDeleteMoved.txt")
1261
+ assertContains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
1262
+ end
1263
+
1264
+ # def test_close
1265
+ # zf = ZipFile.new(TEST_ZIP.zipName)
1266
+ # zf.close
1267
+ # assert_exception(IOError) {
1268
+ # zf.extract(TEST_ZIP.entryNames.first, "hullubullu")
1269
+ # }
1270
+ # end
1271
+
1272
+ def test_compound1
1273
+ renamedName = "renamedName"
1274
+ originalEntries = []
1275
+ begin
1276
+ zf = ZipFile.new(TEST_ZIP.zipName)
1277
+ originalEntries = zf.entries.dup
1278
+
1279
+ assertNotContains(zf, TestFiles::RANDOM_ASCII_FILE1)
1280
+ zf.add(TestFiles::RANDOM_ASCII_FILE1,
1281
+ TestFiles::RANDOM_ASCII_FILE1)
1282
+ assertContains(zf, TestFiles::RANDOM_ASCII_FILE1)
1283
+
1284
+ zf.rename(zf.entries[0], renamedName)
1285
+ assertContains(zf, renamedName)
1286
+
1287
+ TestFiles::BINARY_TEST_FILES.each {
1288
+ |filename|
1289
+ zf.add(filename, filename)
1290
+ assertContains(zf, filename)
1291
+ }
1292
+
1293
+ assertContains(zf, originalEntries.last.to_s)
1294
+ zf.remove(originalEntries.last.to_s)
1295
+ assertNotContains(zf, originalEntries.last.to_s)
1296
+
1297
+ ensure
1298
+ zf.close
1299
+ end
1300
+ begin
1301
+ zfRead = ZipFile.new(TEST_ZIP.zipName)
1302
+ assertContains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
1303
+ assertContains(zfRead, renamedName)
1304
+ TestFiles::BINARY_TEST_FILES.each {
1305
+ |filename|
1306
+ assertContains(zfRead, filename)
1307
+ }
1308
+ assertNotContains(zfRead, originalEntries.last.to_s)
1309
+ ensure
1310
+ zfRead.close
1311
+ end
1312
+ end
1313
+
1314
+ def test_compound2
1315
+ begin
1316
+ zf = ZipFile.new(TEST_ZIP.zipName)
1317
+ originalEntries = zf.entries.dup
1318
+
1319
+ originalEntries.each {
1320
+ |entry|
1321
+ zf.remove(entry)
1322
+ assertNotContains(zf, entry)
1323
+ }
1324
+ assert(zf.entries.empty?)
1325
+
1326
+ TestFiles::ASCII_TEST_FILES.each {
1327
+ |filename|
1328
+ zf.add(filename, filename)
1329
+ assertContains(zf, filename)
1330
+ }
1331
+ assert_equals(zf.entries.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
1332
+
1333
+ zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
1334
+ assertNotContains(zf, TestFiles::ASCII_TEST_FILES[0])
1335
+ assertContains(zf, "newName")
1336
+ ensure
1337
+ zf.close
1338
+ end
1339
+ begin
1340
+ zfRead = ZipFile.new(TEST_ZIP.zipName)
1341
+ asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
1342
+ asciiTestFiles.shift
1343
+ asciiTestFiles.each {
1344
+ |filename|
1345
+ assertContains(zf, filename)
1346
+ }
1347
+
1348
+ assertContains(zf, "newName")
1349
+ ensure
1350
+ zfRead.close
1351
+ end
1352
+ end
1353
+
1354
+ private
1355
+ def assertContains(zf, entryName, filename = entryName)
1356
+ assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
1357
+ assertEntryContents(zf, entryName, filename) if File.exists?(filename)
1358
+ end
1359
+
1360
+ def assertNotContains(zf, entryName)
1361
+ assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
1362
+ end
1363
+ end
1364
+
1365
+ class ZipFileExtractTest < CommonZipFileFixture
1366
+ EXTRACTED_FILENAME = "extEntry"
1367
+ ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entryNames.reverse
1368
+
1369
+ def setup
1370
+ super
1371
+ File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
1372
+ end
1373
+
1374
+ def test_extract
1375
+ ZipFile.open(TEST_ZIP.zipName) {
1376
+ |zf|
1377
+ zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
1378
+
1379
+ assert(File.exists? EXTRACTED_FILENAME)
1380
+ AssertEntry::assertContents(EXTRACTED_FILENAME,
1381
+ zf.getInputStream(ENTRY_TO_EXTRACT) { |is| is.read })
1382
+ }
1383
+ end
1384
+
1385
+ def test_extractExists
1386
+ writtenText = "written text"
1387
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1388
+
1389
+ assert_exception(ZipDestinationFileExistsError) {
1390
+ ZipFile.open(TEST_ZIP.zipName) {
1391
+ |zf|
1392
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME)
1393
+ }
1394
+ }
1395
+ File.open(EXTRACTED_FILENAME, "r") {
1396
+ |f|
1397
+ assert_equals(writtenText, f.read)
1398
+ }
1399
+ end
1400
+
1401
+ def test_extractExistsOverwrite
1402
+ writtenText = "written text"
1403
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1404
+
1405
+ gotCalled = false
1406
+ ZipFile.open(TEST_ZIP.zipName) {
1407
+ |zf|
1408
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME) { gotCalled = true; true }
1409
+ }
1410
+
1411
+ assert(gotCalled)
1412
+ File.open(EXTRACTED_FILENAME, "r") {
1413
+ |f|
1414
+ assert(writtenText != f.read)
1415
+ }
1416
+ end
1417
+
1418
+ def test_extractNonEntry
1419
+ zf = ZipFile.new(TEST_ZIP.zipName)
1420
+ assert_exception(ZipNoSuchEntryError) { zf.extract("nonExistingEntry", "nonExistingEntry") }
1421
+ ensure
1422
+ zf.close if zf
1423
+ end
1424
+
1425
+ def test_extractNonEntry2
1426
+ outFile = "outfile"
1427
+ assert_exception(ZipNoSuchEntryError) {
1428
+ zf = ZipFile.new(TEST_ZIP.zipName)
1429
+ nonEntry = "hotdog-diddelidoo"
1430
+ assert(! zf.entries.include?(nonEntry))
1431
+ zf.extract(nonEntry, outFile)
1432
+ zf.close
1433
+ }
1434
+ assert(! File.exists?(outFile))
1435
+ end
1436
+
1437
+ end
1438
+
1439
+ class ZipFileExtractDirectoryTest < CommonZipFileFixture
1440
+ TEST_OUT_NAME = "emptyOutDir"
1441
+
1442
+ def openZip(&aProc)
1443
+ assert(aProc != nil)
1444
+ ZipFile.open(TestZipFile::TEST_ZIP4.zipName, &aProc)
1445
+ end
1446
+
1447
+ def extractTestDir(&aProc)
1448
+ openZip {
1449
+ |zf|
1450
+ zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
1451
+ }
1452
+ end
1453
+
1454
+ def setup
1455
+ super
1456
+
1457
+ Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
1458
+ File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
1459
+ end
1460
+
1461
+ def test_extractDirectory
1462
+ extractTestDir
1463
+ assert(File.directory? TEST_OUT_NAME)
1464
+ end
1465
+
1466
+ def test_extractDirectoryExistsAsDir
1467
+ Dir.mkdir TEST_OUT_NAME
1468
+ extractTestDir
1469
+ assert(File.directory? TEST_OUT_NAME)
1470
+ end
1471
+
1472
+ def test_extractDirectoryExistsAsFile
1473
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1474
+ assert_exception(ZipDestinationFileExistsError) { extractTestDir }
1475
+ end
1476
+
1477
+ def test_extractDirectoryExistsAsFileOverwrite
1478
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1479
+ gotCalled = false
1480
+ extractTestDir {
1481
+ |entry, destPath|
1482
+ gotCalled = true
1483
+ assert_equals(TEST_OUT_NAME, destPath)
1484
+ assert(entry.isDirectory)
1485
+ true
1486
+ }
1487
+ assert(gotCalled)
1488
+ assert(File.directory? TEST_OUT_NAME)
1489
+ end
1490
+ end
1491
+
1492
+
1493
+ TestFiles::createTestFiles(ARGV.index("recreate") != nil ||
1494
+ ARGV.index("recreateonly") != nil)
1495
+ TestZipFile::createTestZips(ARGV.index("recreate") != nil ||
1496
+ ARGV.index("recreateonly") != nil)
1497
+ exit if ARGV.index("recreateonly") != nil
1498
+
1499
+ #require 'runit/cui/testrunner'
1500
+ #RUNIT::CUI::TestRunner.run(ZipFileTest.suite)
1501
+
1502
+ # Copyright (C) 2002 Thomas Sondergaard
1503
+ # rubyzip is free software; you can redistribute it and/or
1504
+ # modify it under the terms of the ruby license.