rzip 2.1.1

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