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.
- data/ChangeLog.txt +1081 -0
- data/NEWS.txt +147 -0
- data/README +67 -0
- data/Rakefile +64 -0
- data/TODO.txt +16 -0
- data/lib/zip.rb +1 -0
- data/lib/zip/ioextras.rb +155 -0
- data/lib/zip/stdrubyext.rb +111 -0
- data/lib/zip/tempfile_bugfixed.rb +195 -0
- data/lib/zip/version.rb +3 -0
- data/lib/zip/zip.rb +1873 -0
- data/lib/zip/zipfilesystem.rb +609 -0
- data/lib/zip/ziprequire.rb +90 -0
- data/samples/example.rb +69 -0
- data/samples/example_filesystem.rb +34 -0
- data/samples/gtk_zip.rb +86 -0
- data/samples/write_simple.rb +13 -0
- data/samples/zipfind.rb +74 -0
- data/test/data/file1.txt +46 -0
- data/test/data/file1.txt.deflatedData +0 -0
- data/test/data/file2.txt +1504 -0
- data/test/data/notzippedruby.rb +7 -0
- data/test/data/rubycode.zip +0 -0
- data/test/data/rubycode2.zip +0 -0
- data/test/data/testDirectory.bin +0 -0
- data/test/data/zipWithDirs.zip +0 -0
- data/test/gentestfiles.rb +155 -0
- data/test/helper.rb +18 -0
- data/test/test_ioextras.rb +204 -0
- data/test/test_stdrubyext.rb +48 -0
- data/test/test_zip.rb +1649 -0
- data/test/test_zipfilesystem.rb +827 -0
- data/test/test_ziprequire.rb +43 -0
- metadata +109 -0
Binary file
|
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
|
+
}
|
data/test/helper.rb
ADDED
@@ -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.
|
data/test/test_zip.rb
ADDED
@@ -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.
|