metasploit-framework/lib/zip/test/data/generated/longAscii.txt

4513 lines
122 KiB
Ruby

#!/usr/bin/env ruby
$VERBOSE = true
require 'rubyunit'
require 'zip'
include Zip
Dir.chdir "test"
class AbstractInputStreamTest < RUNIT::TestCase
# AbstractInputStream subclass that provides a read method
TEST_LINES = [ "Hello world#{$/}",
"this is the second line#{$/}",
"this is the last line"]
TEST_STRING = TEST_LINES.join
class TestAbstractInputStream
include AbstractInputStream
def initialize(aString)
@contents = aString
@readPointer = 0
end
def read(charsToRead)
retVal=@contents[@readPointer, charsToRead]
@readPointer+=charsToRead
return retVal
end
def produceInput
read(100)
end
def inputFinished?
@contents[@readPointer] == nil
end
end
def setup
@io = TestAbstractInputStream.new(TEST_STRING)
end
def test_gets
assert_equals(TEST_LINES[0], @io.gets)
assert_equals(TEST_LINES[1], @io.gets)
assert_equals(TEST_LINES[2], @io.gets)
assert_equals(nil, @io.gets)
end
def test_getsMultiCharSeperator
assert_equals("Hell", @io.gets("ll"))
assert_equals("o world#{$/}this is the second l", @io.gets("d l"))
end
def test_each_line
lineNumber=0
@io.each_line {
|line|
assert_equals(TEST_LINES[lineNumber], line)
lineNumber+=1
}
end
def test_readlines
assert_equals(TEST_LINES, @io.readlines)
end
def test_readline
test_gets
begin
@io.readline
fail "EOFError expected"
rescue EOFError
end
end
end
class ZipEntryTest < RUNIT::TestCase
TEST_ZIPFILE = "someZipFile.zip"
TEST_COMMENT = "a comment"
TEST_COMPRESSED_SIZE = 1234
TEST_CRC = 325324
TEST_EXTRA = "Some data here"
TEST_COMPRESSIONMETHOD = ZipEntry::DEFLATED
TEST_NAME = "entry name"
TEST_SIZE = 8432
TEST_ISDIRECTORY = false
def test_constructorAndGetters
entry = ZipEntry.new(TEST_ZIPFILE,
TEST_NAME,
TEST_COMMENT,
TEST_EXTRA,
TEST_COMPRESSED_SIZE,
TEST_CRC,
TEST_COMPRESSIONMETHOD,
TEST_SIZE)
assert_equals(TEST_COMMENT, entry.comment)
assert_equals(TEST_COMPRESSED_SIZE, entry.compressedSize)
assert_equals(TEST_CRC, entry.crc)
assert_equals(TEST_EXTRA, entry.extra)
assert_equals(TEST_COMPRESSIONMETHOD, entry.compressionMethod)
assert_equals(TEST_NAME, entry.name)
assert_equals(TEST_SIZE, entry.size)
assert_equals(TEST_ISDIRECTORY, entry.isDirectory)
end
def test_equality
entry1 = ZipEntry.new("file.zip", "name", "isNotCompared",
"something extra", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry2 = ZipEntry.new("file.zip", "name", "isNotComparedXXX",
"something extra", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry3 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extra", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry4 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry5 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 1234,
ZipEntry::DEFLATED, 10000)
entry6 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 123,
ZipEntry::DEFLATED, 10000)
entry7 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 123,
ZipEntry::STORED, 10000)
entry8 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 123,
ZipEntry::STORED, 100000)
assert_equals(entry1, entry1)
assert_equals(entry1, entry2)
assert(entry2 != entry3)
assert(entry3 != entry4)
assert(entry4 != entry5)
assert(entry5 != entry6)
assert(entry6 != entry7)
assert(entry7 != entry8)
assert(entry7 != "hello")
assert(entry7 != 12)
end
end
module IOizeString
attr_reader :tell
def read(count = nil)
@tell ||= 0
count = size unless count
retVal = slice(@tell, count)
@tell += count
return retVal
end
def seek(index, offset)
@tell ||= 0
case offset
when IO::SEEK_END
newPos = size + index
when IO::SEEK_SET
newPos = index
when IO::SEEK_CUR
newPos = @tell + index
else
raise "Error in test method IOizeString::seek"
end
if (newPos < 0 || newPos >= size)
raise Errno::EINVAL
else
@tell=newPos
end
end
def reset
@tell = 0
end
end
class ZipLocalEntryTest < RUNIT::TestCase
def test_readLocalEntryHeaderOfFirstTestZipEntry
File.open(TestZipFile::TEST_ZIP3.zipName) {
|file|
entry = ZipEntry.readLocalEntry(file)
assert_equal("", entry.comment)
# Differs from windows and unix because of CR LF
# assert_equal(480, entry.compressedSize)
# assert_equal(0x2a27930f, entry.crc)
# extra field is 21 bytes long
# probably contains some unix attrutes or something
# disabled: assert_equal(nil, entry.extra)
assert_equal(ZipEntry::DEFLATED, entry.compressionMethod)
assert_equal(TestZipFile::TEST_ZIP3.entryNames[0], entry.name)
assert_equal(File.size(TestZipFile::TEST_ZIP3.entryNames[0]), entry.size)
assert(! entry.isDirectory)
}
end
def test_readLocalEntryFromNonZipFile
File.open("ziptest.rb") {
|file|
assert_equals(nil, ZipEntry.readLocalEntry(file))
}
end
def test_readLocalEntryFromTruncatedZipFile
zipFragment=""
File.open(TestZipFile::TEST_ZIP2.zipName) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
zipFragment.extend(IOizeString).reset
entry = ZipEntry.new
entry.readLocalEntry(zipFragment)
fail "ZipError expected"
rescue ZipError
end
def test_writeEntry
entry = ZipEntry.new("file.zip", "entryName", "my little comment",
"thisIsSomeExtraInformation", 100, 987654,
ZipEntry::DEFLATED, 400)
writeToFile("localEntryHeader.bin", "centralEntryHeader.bin", entry)
entryReadLocal, entryReadCentral = readFromFile("localEntryHeader.bin", "centralEntryHeader.bin")
compareLocalEntryHeaders(entry, entryReadLocal)
compareCDirEntryHeaders(entry, entryReadCentral)
end
private
def compareLocalEntryHeaders(entry1, entry2)
assert_equals(entry1.compressedSize , entry2.compressedSize)
assert_equals(entry1.crc , entry2.crc)
assert_equals(entry1.extra , entry2.extra)
assert_equals(entry1.compressionMethod, entry2.compressionMethod)
assert_equals(entry1.name , entry2.name)
assert_equals(entry1.size , entry2.size)
assert_equals(entry1.localHeaderOffset, entry2.localHeaderOffset)
end
def compareCDirEntryHeaders(entry1, entry2)
compareLocalEntryHeaders(entry1, entry2)
assert_equals(entry1.comment, entry2.comment)
end
def writeToFile(localFileName, centralFileName, entry)
File.open(localFileName, "wb") { |f| entry.writeLocalEntry(f) }
File.open(centralFileName, "wb") { |f| entry.writeCDirEntry(f) }
end
def readFromFile(localFileName, centralFileName)
localEntry = nil
cdirEntry = nil
File.open(localFileName, "rb") { |f| localEntry = ZipEntry.readLocalEntry(f) }
File.open(centralFileName, "rb") { |f| cdirEntry = ZipEntry.readCDirEntry(f) }
return [localEntry, cdirEntry]
end
end
module DecompressorTests
# expects @refText and @decompressor
def test_readEverything
assert_equals(@refText, @decompressor.read)
end
def test_readInChunks
chunkSize = 5
while (decompressedChunk = @decompressor.read(chunkSize))
assert_equals(@refText.slice!(0, chunkSize), decompressedChunk)
end
assert_equals(0, @refText.size)
end
end
class InflaterTest < RUNIT::TestCase
include DecompressorTests
def setup
@file = File.new("file1.txt.deflatedData", "rb")
@refText=""
File.open("file1.txt") { |f| @refText = f.read }
@decompressor = Inflater.new(@file)
end
def teardown
@file.close
end
end
class PassThruDecompressorTest < RUNIT::TestCase
include DecompressorTests
TEST_FILE="file1.txt"
def setup
@file = File.new(TEST_FILE)
@refText=""
File.open(TEST_FILE) { |f| @refText = f.read }
@decompressor = PassThruDecompressor.new(@file, File.size(TEST_FILE))
end
def teardown
@file.close
end
end
module AssertEntry
def assertNextEntry(filename, zis)
assertEntry(filename, zis, zis.getNextEntry.name)
end
def assertEntry(filename, zis, entryName)
assert_equals(filename, entryName)
assertEntryContentsForStream(filename, zis, entryName)
end
def assertEntryContentsForStream(filename, zis, entryName)
File.open(filename, "rb") {
|file|
expected = file.read
actual = zis.read
if (expected != actual)
if (expected.length > 400 || actual.length > 400)
zipEntryFilename=entryName+".zipEntry"
File.open(zipEntryFilename, "wb") { |file| file << actual }
fail("File '#{filename}' is different from '#{zipEntryFilename}'")
else
assert_equals(expected, actual)
end
end
}
end
def AssertEntry.assertContents(filename, aString)
fileContents = ""
File.open(filename, "rb") { |f| fileContents = f.read }
if (fileContents != aString)
if (expected.length > 400 || actual.length > 400)
stringFile = filename + ".other"
File.open(stringFile, "wb") { |f| f << aString }
fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
else
assert_equals(expected, actual)
end
end
end
def assertStreamContents(zis, testZipFile)
assert(zis != nil)
testZipFile.entryNames.each {
|entryName|
assertNextEntry(entryName, zis)
}
assert_equals(nil, zis.getNextEntry)
end
def assertTestZipContents(testZipFile)
ZipInputStream.open(testZipFile.zipName) {
|zis|
assertStreamContents(zis, testZipFile)
}
end
def assertEntryContents(zipFile, entryName, filename = entryName.to_s)
zis = zipFile.getInputStream(entryName)
assertEntryContentsForStream(filename, zis, entryName)
ensure
zis.close if zis
end
end
class ZipInputStreamTest < RUNIT::TestCase
include AssertEntry
def test_new
zis = ZipInputStream.new(TestZipFile::TEST_ZIP2.zipName)
assertStreamContents(zis, TestZipFile::TEST_ZIP2)
zis.close
end
def test_openWithBlock
ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName) {
|zis|
assertStreamContents(zis, TestZipFile::TEST_ZIP2)
}
end
def test_openWithoutBlock
zis = ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName)
assertStreamContents(zis, TestZipFile::TEST_ZIP2)
end
def test_incompleteReads
ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName) {
|zis|
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[0], entry.name)
assert zis.gets.length > 0
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[1], entry.name)
assert_equals(0, entry.size)
assert_equals(nil, zis.gets)
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[2], entry.name)
assert zis.gets.length > 0
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[3], entry.name)
assert zis.gets.length > 0
}
end
end
class TestFiles
RANDOM_ASCII_FILE1 = "randomAscii1.txt"
RANDOM_ASCII_FILE2 = "randomAscii2.txt"
RANDOM_ASCII_FILE3 = "randomAscii3.txt"
RANDOM_BINARY_FILE1 = "randomBinary1.bin"
RANDOM_BINARY_FILE2 = "randomBinary2.bin"
EMPTY_TEST_DIR = "emptytestdir"
ASCII_TEST_FILES = [ RANDOM_ASCII_FILE1, RANDOM_ASCII_FILE2, RANDOM_ASCII_FILE3 ]
BINARY_TEST_FILES = [ RANDOM_BINARY_FILE1, RANDOM_BINARY_FILE2 ]
TEST_DIRECTORIES = [ EMPTY_TEST_DIR ]
TEST_FILES = [ ASCII_TEST_FILES, BINARY_TEST_FILES, EMPTY_TEST_DIR ].flatten!
def TestFiles.createTestFiles(recreate)
if (recreate ||
! (TEST_FILES.inject(true) { |accum, element| accum && File.exists?(element) }))
ASCII_TEST_FILES.each_with_index {
|filename, index|
createRandomAscii(filename, 1E4 * (index+1))
}
BINARY_TEST_FILES.each_with_index {
|filename, index|
createRandomBinary(filename, 1E4 * (index+1))
}
ensureDir(EMPTY_TEST_DIR)
end
end
private
def TestFiles.createRandomAscii(filename, size)
File.open(filename, "wb") {
|file|
while (file.tell < size)
file << rand
end
}
end
def TestFiles.createRandomBinary(filename, size)
File.open(filename, "wb") {
|file|
while (file.tell < size)
file << rand.to_a.pack("V")
end
}
end
def TestFiles.ensureDir(name)
if File.exists?(name)
return if File.stat(name).directory?
File.delete(name)
end
Dir.mkdir(name)
end
end
# For representation and creation of
# test data
class TestZipFile
attr_accessor :zipName, :entryNames, :comment
def initialize(zipName, entryNames, comment = "")
@zipName=zipName
@entryNames=entryNames
@comment = comment
end
def TestZipFile.createTestZips(recreate)
files = Dir.entries(".")
if (recreate ||
! (files.index(TEST_ZIP1.zipName) &&
files.index(TEST_ZIP2.zipName) &&
files.index(TEST_ZIP3.zipName) &&
files.index(TEST_ZIP4.zipName) &&
files.index("empty.txt") &&
files.index("short.txt") &&
files.index("longAscii.txt") &&
files.index("longBinary.bin") ))
raise "failed to create test zip '#{TEST_ZIP1.zipName}'" unless
system("zip #{TEST_ZIP1.zipName} ziptest.rb")
raise "failed to remove entry from '#{TEST_ZIP1.zipName}'" unless
system("zip #{TEST_ZIP1.zipName} -d ziptest.rb")
File.open("empty.txt", "w") {}
File.open("short.txt", "w") { |file| file << "ABCDEF" }
ziptestTxt=""
File.open("ziptest.rb") { |file| ziptestTxt=file.read }
File.open("longAscii.txt", "w") {
|file|
while (file.tell < 1E5)
file << ziptestTxt
end
}
testBinaryPattern=""
File.open("empty.zip") { |file| testBinaryPattern=file.read }
testBinaryPattern *= 4
File.open("longBinary.bin", "wb") {
|file|
while (file.tell < 3E5)
file << testBinaryPattern << rand
end
}
raise "failed to create test zip '#{TEST_ZIP2.zipName}'" unless
system("zip #{TEST_ZIP2.zipName} #{TEST_ZIP2.entryNames.join(' ')}")
# without bash system interprets everything after echo as parameters to
# echo including | zip -z ...
raise "failed to add comment to test zip '#{TEST_ZIP2.zipName}'" unless
system("bash -c \"echo #{TEST_ZIP2.comment} | zip -z #{TEST_ZIP2.zipName}\"")
raise "failed to create test zip '#{TEST_ZIP3.zipName}'" unless
system("zip #{TEST_ZIP3.zipName} #{TEST_ZIP3.entryNames.join(' ')}")
raise "failed to create test zip '#{TEST_ZIP4.zipName}'" unless
system("zip #{TEST_ZIP4.zipName} #{TEST_ZIP4.entryNames.join(' ')}")
end
rescue
raise $!.to_s +
"\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" +
"to create test data. If you don't have it you can download\n" +
"the necessary test files at http://sf.net/projects/rubyzip."
end
TEST_ZIP1 = TestZipFile.new("empty.zip", [])
TEST_ZIP2 = TestZipFile.new("4entry.zip", %w{ longAscii.txt empty.txt short.txt longBinary.bin},
"my zip comment")
TEST_ZIP3 = TestZipFile.new("test1.zip", %w{ file1.txt })
TEST_ZIP4 = TestZipFile.new("zipWithDir.zip", [ "file1.txt",
TestFiles::EMPTY_TEST_DIR])
end
class AbstractOutputStreamTest < RUNIT::TestCase
class TestOutputStream
include AbstractOutputStream
attr_accessor :buffer
def initialize
@buffer = ""
end
def << (data)
@buffer << data
self
end
end
def setup
@outputStream = TestOutputStream.new
@origCommaSep = $,
@origOutputSep = $\
end
def teardown
$, = @origCommaSep
$\ = @origOutputSep
end
def test_write
count = @outputStream.write("a little string")
assert_equals("a little string", @outputStream.buffer)
assert_equals("a little string".length, count)
count = @outputStream.write(". a little more")
assert_equals("a little string. a little more", @outputStream.buffer)
assert_equals(". a little more".length, count)
end
def test_print
$\ = nil # record separator set to nil
@outputStream.print("hello")
assert_equals("hello", @outputStream.buffer)
@outputStream.print(" world.")
assert_equals("hello world.", @outputStream.buffer)
@outputStream.print(" You ok ", "out ", "there?")
assert_equals("hello world. You ok out there?", @outputStream.buffer)
$\ = "\n"
@outputStream.print
assert_equals("hello world. You ok out there?\n", @outputStream.buffer)
@outputStream.print("I sure hope so!")
assert_equals("hello world. You ok out there?\nI sure hope so!\n", @outputStream.buffer)
$, = "X"
@outputStream.buffer = ""
@outputStream.print("monkey", "duck", "zebra")
assert_equals("monkeyXduckXzebra\n", @outputStream.buffer)
$\ = nil
@outputStream.buffer = ""
@outputStream.print(20)
assert_equals("20", @outputStream.buffer)
end
def test_printf
@outputStream.printf("%d %04x", 123, 123)
assert_equals("123 007b", @outputStream.buffer)
end
def test_putc
@outputStream.putc("A")
assert_equals("A", @outputStream.buffer)
@outputStream.putc(65)
assert_equals("AA", @outputStream.buffer)
end
def test_puts
@outputStream.puts
assert_equals("\n", @outputStream.buffer)
@outputStream.puts("hello", "world")
assert_equals("\nhello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts("hello\n", "world\n")
assert_equals("hello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(["hello\n", "world\n"])
assert_equals("hello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(["hello\n", "world\n"], "bingo")
assert_equals("hello\nworld\nbingo\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(16, 20, 50, "hello")
assert_equals("16\n20\n50\nhello\n", @outputStream.buffer)
end
end
module CrcTest
def runCrcTest(compressorClass)
str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
fakeOut = AbstractOutputStreamTest::TestOutputStream.new
deflater = compressorClass.new(fakeOut)
deflater << str
assert_equals(0x919920fc, deflater.crc)
end
end
class PassThruCompressorTest < RUNIT::TestCase
include CrcTest
def test_size
File.open("dummy.txt", "wb") {
|file|
compressor = PassThruCompressor.new(file)
assert_equals(0, compressor.size)
t1 = "hello world"
t2 = ""
t3 = "bingo"
compressor << t1
assert_equals(compressor.size, t1.size)
compressor << t2
assert_equals(compressor.size, t1.size + t2.size)
compressor << t3
assert_equals(compressor.size, t1.size + t2.size + t3.size)
}
end
def test_crc
runCrcTest(PassThruCompressor)
end
end
class DeflaterTest < RUNIT::TestCase
include CrcTest
def test_outputOperator
txt = loadFile("ziptest.rb")
deflate(txt, "deflatertest.bin")
inflatedTxt = inflate("deflatertest.bin")
assert_equals(txt, inflatedTxt)
end
private
def loadFile(fileName)
txt = nil
File.open(fileName, "rb") { |f| txt = f.read }
end
def deflate(data, fileName)
File.open(fileName, "wb") {
|file|
deflater = Deflater.new(file)
deflater << data
deflater.finish
assert_equals(deflater.size, data.size)
file << "trailing data for zlib with -MAX_WBITS"
}
end
def inflate(fileName)
txt = nil
File.open(fileName, "rb") {
|file|
inflater = Inflater.new(file)
txt = inflater.read
}
end
def test_crc
runCrcTest(Deflater)
end
end
class ZipOutputStreamTest < RUNIT::TestCase
include AssertEntry
TEST_ZIP = TestZipFile::TEST_ZIP2.clone
TEST_ZIP.zipName = "output.zip"
def test_new
zos = ZipOutputStream.new(TEST_ZIP.zipName)
zos.comment = TEST_ZIP.comment
writeTestZip(zos)
zos.close
assertTestZipContents(TEST_ZIP)
end
def test_open
ZipOutputStream.open(TEST_ZIP.zipName) {
|zos|
zos.comment = TEST_ZIP.comment
writeTestZip(zos)
}
assertTestZipContents(TEST_ZIP)
end
def test_writingToClosedStream
assertIOErrorInClosedStream { |zos| zos << "hello world" }
assertIOErrorInClosedStream { |zos| zos.puts "hello world" }
assertIOErrorInClosedStream { |zos| zos.write "hello world" }
end
def test_cannotOpenFile
name = TestFiles::EMPTY_TEST_DIR
begin
zos = ZipOutputStream.open(name)
rescue Exception
assert($!.kind_of?(Errno::EISDIR) || # Linux
$!.kind_of?(Errno::EEXIST) || # Windows/cygwin
$!.kind_of?(Errno::EACCES), # Windows
"Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.type}")
end
end
def assertIOErrorInClosedStream
assert_exception(IOError) {
zos = ZipOutputStream.new("test_putOnClosedStream.zip")
zos.close
yield zos
}
end
def writeTestZip(zos)
TEST_ZIP.entryNames.each {
|entryName|
zos.putNextEntry(entryName)
File.open(entryName, "rb") { |f| zos.write(f.read) }
}
end
end
module Enumerable
def compareEnumerables(otherEnumerable)
otherAsArray = otherEnumerable.to_a
index=0
each_with_index {
|element, index|
return false unless yield(element, otherAsArray[index])
}
return index+1 == otherAsArray.size
end
end
class ZipCentralDirectoryEntryTest < RUNIT::TestCase
def test_readFromStream
File.open("testDirectory.bin", "rb") {
|file|
entry = ZipEntry.readCDirEntry(file)
assert_equals("longAscii.txt", entry.name)
assert_equals(ZipEntry::DEFLATED, entry.compressionMethod)
assert_equals(106490, entry.size)
assert_equals(3784, entry.compressedSize)
assert_equals(0xfcd1799c, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals("empty.txt", entry.name)
assert_equals(ZipEntry::STORED, entry.compressionMethod)
assert_equals(0, entry.size)
assert_equals(0, entry.compressedSize)
assert_equals(0x0, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals("short.txt", entry.name)
assert_equals(ZipEntry::STORED, entry.compressionMethod)
assert_equals(6, entry.size)
assert_equals(6, entry.compressedSize)
assert_equals(0xbb76fe69, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals("longBinary.bin", entry.name)
assert_equals(ZipEntry::DEFLATED, entry.compressionMethod)
assert_equals(1000024, entry.size)
assert_equals(70847, entry.compressedSize)
assert_equals(0x10da7d59, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals(nil, entry)
# Fields that are not check by this test:
# version made by 2 bytes
# version needed to extract 2 bytes
# general purpose bit flag 2 bytes
# last mod file time 2 bytes
# last mod file date 2 bytes
# compressed size 4 bytes
# uncompressed size 4 bytes
# disk number start 2 bytes
# internal file attributes 2 bytes
# external file attributes 4 bytes
# relative offset of local header 4 bytes
# file name (variable size)
# extra field (variable size)
# file comment (variable size)
}
end
def test_ReadEntryFromTruncatedZipFile
fragment=""
File.open("testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
fragment.extend(IOizeString)
entry = ZipEntry.new
entry.readCDirEntry(fragment)
fail "ZipError expected"
rescue ZipError
end
end
class ZipCentralDirectoryTest < RUNIT::TestCase
def test_readFromStream
File.open(TestZipFile::TEST_ZIP2.zipName, "rb") {
|zipFile|
cdir = ZipCentralDirectory.readFromStream(zipFile)
assert_equals(TestZipFile::TEST_ZIP2.entryNames.size, cdir.size)
assert(cdir.compareEnumerables(TestZipFile::TEST_ZIP2.entryNames) {
|cdirEntry, testEntryName|
cdirEntry.name == testEntryName
})
assert_equals(TestZipFile::TEST_ZIP2.comment, cdir.comment)
}
end
def test_readFromInvalidStream
File.open("ziptest.rb", "rb") {
|zipFile|
cdir = ZipCentralDirectory.new
cdir.readFromStream(zipFile)
}
fail "ZipError expected!"
rescue ZipError
end
def test_ReadFromTruncatedZipFile
fragment=""
File.open("testDirectory.bin") { |f| fragment = f.read }
fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
fragment.extend(IOizeString)
entry = ZipCentralDirectory.new
entry.readFromStream(fragment)
fail "ZipError expected"
rescue ZipError
end
def test_writeToStream
entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
cdir = ZipCentralDirectory.new(entries, "my zip comment")
File.open("cdirtest.bin", "wb") { |f| cdir.writeToStream(f) }
cdirReadback = ZipCentralDirectory.new
File.open("cdirtest.bin", "rb") { |f| cdirReadback.readFromStream(f) }
assert_equals(cdir.entries, cdirReadback.entries)
end
def test_equality
cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"my zip comment")
cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"my zip comment")
cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"comment?")
cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"comment?")
assert_equals(cdir1, cdir1)
assert_equals(cdir1, cdir2)
assert(cdir1 != cdir3)
assert(cdir2 != cdir3)
assert(cdir2 != cdir3)
assert(cdir3 != cdir4)
assert(cdir3 != "hello")
end
end
class BasicZipFileTest < RUNIT::TestCase
include AssertEntry
def setup
@zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zipName)
@testEntryNameIndex=0
end
def nextTestEntryName
retVal=TestZipFile::TEST_ZIP2.entryNames[@testEntryNameIndex]
@testEntryNameIndex+=1
return retVal
end
def test_entries
assert_equals(TestZipFile::TEST_ZIP2.entryNames, @zipFile.entries.map {|e| e.name} )
end
def test_each
@zipFile.each {
|entry|
assert_equals(nextTestEntryName, entry.name)
}
assert_equals(4, @testEntryNameIndex)
end
def test_foreach
ZipFile.foreach(TestZipFile::TEST_ZIP2.zipName) {
|entry|
assert_equals(nextTestEntryName, entry.name)
}
assert_equals(4, @testEntryNameIndex)
end
def test_getInputStream
@zipFile.each {
|entry|
assertEntry(nextTestEntryName, @zipFile.getInputStream(entry),
entry.name)
}
assert_equals(4, @testEntryNameIndex)
end
def test_getInputStreamBlock
fileAndEntryName = @zipFile.entries.first.name
@zipFile.getInputStream(fileAndEntryName) {
|zis|
assertEntryContentsForStream(fileAndEntryName,
zis,
fileAndEntryName)
}
end
end
class CommonZipFileFixture < RUNIT::TestCase
include AssertEntry
EMPTY_FILENAME = "emptyZipFile.zip"
TEST_ZIP = TestZipFile::TEST_ZIP2.clone
TEST_ZIP.zipName = "4entry_copy.zip"
def setup
File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
File.copy(TestZipFile::TEST_ZIP2.zipName, TEST_ZIP.zipName)
end
end
class ZipFileTest < CommonZipFileFixture
def test_createFromScratch
comment = "a short comment"
zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
zf.comment = comment
zf.close
zfRead = ZipFile.new(EMPTY_FILENAME)
assert_equals(comment, zfRead.comment)
assert_equals(0, zfRead.entries.length)
end
def test_add
srcFile = "ziptest.rb"
entryName = "newEntryName.rb"
assert(File.exists? srcFile)
zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
zf.add(entryName, srcFile)
zf.close
zfRead = ZipFile.new(EMPTY_FILENAME)
assert_equals("", zfRead.comment)
assert_equals(1, zfRead.entries.length)
assert_equals(entryName, zfRead.entries.first.name)
AssertEntry.assertContents(srcFile,
zfRead.getInputStream(entryName) { |zis| zis.read })
end
def test_addExistingEntryName
assert_exception(ZipEntryExistsError) {
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.add(zf.entries.first.name, "ziptest.rb")
}
}
end
def test_addExistingEntryNameReplace
gotCalled = false
replacedEntry = nil
ZipFile.open(TEST_ZIP.zipName) {
|zf|
replacedEntry = zf.entries.first.name
zf.add(replacedEntry, "ziptest.rb") { gotCalled = true; true }
}
assert(gotCalled)
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assertContains(zf, replacedEntry, "ziptest.rb")
}
end
def test_addDirectory
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
}
ZipFile.open(TEST_ZIP.zipName) {
|zf|
dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
assert(dirEntry.isDirectory)
}
end
def test_remove
entryToRemove, *remainingEntries = TEST_ZIP.entryNames
File.copy(TestZipFile::TEST_ZIP2.zipName, TEST_ZIP.zipName)
zf = ZipFile.new(TEST_ZIP.zipName)
assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
zf.remove(entryToRemove)
assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
assert_equals(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
zf.close
zfRead = ZipFile.new(TEST_ZIP.zipName)
assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
assert_equals(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
zfRead.close
end
def test_rename
entryToRename, *remainingEntries = TEST_ZIP.entryNames
zf = ZipFile.new(TEST_ZIP.zipName)
assert(zf.entries.map { |e| e.name }.include? entryToRename)
newName = "changed name"
assert(! zf.entries.map { |e| e.name }.include?(newName))
zf.rename(entryToRename, newName)
assert(zf.entries.map { |e| e.name }.include? newName)
zf.close
zfRead = ZipFile.new(TEST_ZIP.zipName)
assert(zfRead.entries.map { |e| e.name }.include? newName)
zfRead.close
end
def test_renameToExistingEntry
oldEntries = nil
ZipFile.open(TEST_ZIP.zipName) { |zf| oldEntries = zf.entries }
assert_exception(ZipEntryExistsError) {
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.rename(zf.entries[0], zf.entries[1].name)
}
}
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assert_equals(oldEntries.map{ |e| e.name }, zf.entries.map{ |e| e.name })
}
end
def test_renameToExistingEntryOverwrite
oldEntries = nil
ZipFile.open(TEST_ZIP.zipName) { |zf| oldEntries = zf.entries }
gotCalled = false
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
}
assert(gotCalled)
oldEntries.delete_at(0)
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assert_equals(oldEntries.map{ |e| e.name },
zf.entries.map{ |e| e.name })
}
end
def test_renameNonEntry
nonEntry = "bogusEntry"
targetEntry = "targetEntryName"
zf = ZipFile.new(TEST_ZIP.zipName)
assert(! zf.entries.include?(nonEntry))
assert_exception(ZipNoSuchEntryError) {
zf.rename(nonEntry, targetEntry)
}
zf.commit
assert(! zf.entries.include?(targetEntry))
ensure
zf.close
end
def test_renameEntryToExistingEntry
entry1, entry2, *remaining = TEST_ZIP.entryNames
zf = ZipFile.new(TEST_ZIP.zipName)
assert_exception(ZipEntryExistsError) {
zf.rename(entry1, entry2)
}
ensure
zf.close
end
def test_replace
unchangedEntries = TEST_ZIP.entryNames.dup
entryToReplace = unchangedEntries.delete_at(2)
newEntrySrcFilename = "ziptest.rb"
zf = ZipFile.new(TEST_ZIP.zipName)
zf.replace(entryToReplace, newEntrySrcFilename)
zf.close
zfRead = ZipFile.new(TEST_ZIP.zipName)
AssertEntry::assertContents(newEntrySrcFilename,
zfRead.getInputStream(entryToReplace) { |is| is.read })
zfRead.close
end
def test_replaceNonEntry
entryToReplace = "nonExistingEntryname"
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assert_exception(ZipNoSuchEntryError) {
zf.replace(entryToReplace, "ziptest.rb")
}
}
end
def test_commit
newName = "renamedFirst"
zf = ZipFile.new(TEST_ZIP.zipName)
oldName = zf.entries.first
zf.rename(oldName, newName)
zf.commit
zfRead = ZipFile.new(TEST_ZIP.zipName)
assert(zfRead.entries.detect { |e| e.name == newName } != nil)
assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
zfRead.close
zf.close
end
# This test tests that after commit, you
# can delete the file you used to add the entry to the zip file
# with
def test_commitUseZipEntry
File.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
zf = ZipFile.open(TEST_ZIP.zipName)
zf.add("okToDelete.txt", "okToDelete.txt")
assertContains(zf, "okToDelete.txt")
zf.commit
File.move("okToDelete.txt", "okToDeleteMoved.txt")
assertContains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
end
# def test_close
# zf = ZipFile.new(TEST_ZIP.zipName)
# zf.close
# assert_exception(IOError) {
# zf.extract(TEST_ZIP.entryNames.first, "hullubullu")
# }
# end
def test_compound1
renamedName = "renamedName"
originalEntries = []
begin
zf = ZipFile.new(TEST_ZIP.zipName)
originalEntries = zf.entries.dup
assertNotContains(zf, TestFiles::RANDOM_ASCII_FILE1)
zf.add(TestFiles::RANDOM_ASCII_FILE1,
TestFiles::RANDOM_ASCII_FILE1)
assertContains(zf, TestFiles::RANDOM_ASCII_FILE1)
zf.rename(zf.entries[0], renamedName)
assertContains(zf, renamedName)
TestFiles::BINARY_TEST_FILES.each {
|filename|
zf.add(filename, filename)
assertContains(zf, filename)
}
assertContains(zf, originalEntries.last.to_s)
zf.remove(originalEntries.last.to_s)
assertNotContains(zf, originalEntries.last.to_s)
ensure
zf.close
end
begin
zfRead = ZipFile.new(TEST_ZIP.zipName)
assertContains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
assertContains(zfRead, renamedName)
TestFiles::BINARY_TEST_FILES.each {
|filename|
assertContains(zfRead, filename)
}
assertNotContains(zfRead, originalEntries.last.to_s)
ensure
zfRead.close
end
end
def test_compound2
begin
zf = ZipFile.new(TEST_ZIP.zipName)
originalEntries = zf.entries.dup
originalEntries.each {
|entry|
zf.remove(entry)
assertNotContains(zf, entry)
}
assert(zf.entries.empty?)
TestFiles::ASCII_TEST_FILES.each {
|filename|
zf.add(filename, filename)
assertContains(zf, filename)
}
assert_equals(zf.entries.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
assertNotContains(zf, TestFiles::ASCII_TEST_FILES[0])
assertContains(zf, "newName")
ensure
zf.close
end
begin
zfRead = ZipFile.new(TEST_ZIP.zipName)
asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
asciiTestFiles.shift
asciiTestFiles.each {
|filename|
assertContains(zf, filename)
}
assertContains(zf, "newName")
ensure
zfRead.close
end
end
private
def assertContains(zf, entryName, filename = entryName)
assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
assertEntryContents(zf, entryName, filename) if File.exists?(filename)
end
def assertNotContains(zf, entryName)
assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
end
end
class ZipFileExtractTest < CommonZipFileFixture
EXTRACTED_FILENAME = "extEntry"
ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entryNames.reverse
def setup
super
File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
end
def test_extract
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
assert(File.exists? EXTRACTED_FILENAME)
AssertEntry::assertContents(EXTRACTED_FILENAME,
zf.getInputStream(ENTRY_TO_EXTRACT) { |is| is.read })
}
end
def test_extractExists
writtenText = "written text"
File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
assert_exception(ZipDestinationFileExistsError) {
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.extract(zf.entries.first, EXTRACTED_FILENAME)
}
}
File.open(EXTRACTED_FILENAME, "r") {
|f|
assert_equals(writtenText, f.read)
}
end
def test_extractExistsOverwrite
writtenText = "written text"
File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
gotCalled = false
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.extract(zf.entries.first, EXTRACTED_FILENAME) { gotCalled = true; true }
}
assert(gotCalled)
File.open(EXTRACTED_FILENAME, "r") {
|f|
assert(writtenText != f.read)
}
end
def test_extractNonEntry
zf = ZipFile.new(TEST_ZIP.zipName)
assert_exception(ZipNoSuchEntryError) { zf.extract("nonExistingEntry", "nonExistingEntry") }
ensure
zf.close if zf
end
def test_extractNonEntry2
outFile = "outfile"
assert_exception(ZipNoSuchEntryError) {
zf = ZipFile.new(TEST_ZIP.zipName)
nonEntry = "hotdog-diddelidoo"
assert(! zf.entries.include?(nonEntry))
zf.extract(nonEntry, outFile)
zf.close
}
assert(! File.exists?(outFile))
end
end
class ZipFileExtractDirectoryTest < CommonZipFileFixture
TEST_OUT_NAME = "emptyOutDir"
def openZip(&aProc)
assert(aProc != nil)
ZipFile.open(TestZipFile::TEST_ZIP4.zipName, &aProc)
end
def extractTestDir(&aProc)
openZip {
|zf|
zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
}
end
def setup
super
Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
end
def test_extractDirectory
extractTestDir
assert(File.directory? TEST_OUT_NAME)
end
def test_extractDirectoryExistsAsDir
Dir.mkdir TEST_OUT_NAME
extractTestDir
assert(File.directory? TEST_OUT_NAME)
end
def test_extractDirectoryExistsAsFile
File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
assert_exception(ZipDestinationFileExistsError) { extractTestDir }
end
def test_extractDirectoryExistsAsFileOverwrite
File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
gotCalled = false
extractTestDir {
|entry, destPath|
gotCalled = true
assert_equals(TEST_OUT_NAME, destPath)
assert(entry.isDirectory)
true
}
assert(gotCalled)
assert(File.directory? TEST_OUT_NAME)
end
end
TestFiles::createTestFiles(ARGV.index("recreate") != nil ||
ARGV.index("recreateonly") != nil)
TestZipFile::createTestZips(ARGV.index("recreate") != nil ||
ARGV.index("recreateonly") != nil)
exit if ARGV.index("recreateonly") != nil
#require 'runit/cui/testrunner'
#RUNIT::CUI::TestRunner.run(ZipFileTest.suite)
# Copyright (C) 2002 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.
#!/usr/bin/env ruby
$VERBOSE = true
require 'rubyunit'
require 'zip'
include Zip
Dir.chdir "test"
class AbstractInputStreamTest < RUNIT::TestCase
# AbstractInputStream subclass that provides a read method
TEST_LINES = [ "Hello world#{$/}",
"this is the second line#{$/}",
"this is the last line"]
TEST_STRING = TEST_LINES.join
class TestAbstractInputStream
include AbstractInputStream
def initialize(aString)
@contents = aString
@readPointer = 0
end
def read(charsToRead)
retVal=@contents[@readPointer, charsToRead]
@readPointer+=charsToRead
return retVal
end
def produceInput
read(100)
end
def inputFinished?
@contents[@readPointer] == nil
end
end
def setup
@io = TestAbstractInputStream.new(TEST_STRING)
end
def test_gets
assert_equals(TEST_LINES[0], @io.gets)
assert_equals(TEST_LINES[1], @io.gets)
assert_equals(TEST_LINES[2], @io.gets)
assert_equals(nil, @io.gets)
end
def test_getsMultiCharSeperator
assert_equals("Hell", @io.gets("ll"))
assert_equals("o world#{$/}this is the second l", @io.gets("d l"))
end
def test_each_line
lineNumber=0
@io.each_line {
|line|
assert_equals(TEST_LINES[lineNumber], line)
lineNumber+=1
}
end
def test_readlines
assert_equals(TEST_LINES, @io.readlines)
end
def test_readline
test_gets
begin
@io.readline
fail "EOFError expected"
rescue EOFError
end
end
end
class ZipEntryTest < RUNIT::TestCase
TEST_ZIPFILE = "someZipFile.zip"
TEST_COMMENT = "a comment"
TEST_COMPRESSED_SIZE = 1234
TEST_CRC = 325324
TEST_EXTRA = "Some data here"
TEST_COMPRESSIONMETHOD = ZipEntry::DEFLATED
TEST_NAME = "entry name"
TEST_SIZE = 8432
TEST_ISDIRECTORY = false
def test_constructorAndGetters
entry = ZipEntry.new(TEST_ZIPFILE,
TEST_NAME,
TEST_COMMENT,
TEST_EXTRA,
TEST_COMPRESSED_SIZE,
TEST_CRC,
TEST_COMPRESSIONMETHOD,
TEST_SIZE)
assert_equals(TEST_COMMENT, entry.comment)
assert_equals(TEST_COMPRESSED_SIZE, entry.compressedSize)
assert_equals(TEST_CRC, entry.crc)
assert_equals(TEST_EXTRA, entry.extra)
assert_equals(TEST_COMPRESSIONMETHOD, entry.compressionMethod)
assert_equals(TEST_NAME, entry.name)
assert_equals(TEST_SIZE, entry.size)
assert_equals(TEST_ISDIRECTORY, entry.isDirectory)
end
def test_equality
entry1 = ZipEntry.new("file.zip", "name", "isNotCompared",
"something extra", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry2 = ZipEntry.new("file.zip", "name", "isNotComparedXXX",
"something extra", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry3 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extra", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry4 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry5 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 1234,
ZipEntry::DEFLATED, 10000)
entry6 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 123,
ZipEntry::DEFLATED, 10000)
entry7 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 123,
ZipEntry::STORED, 10000)
entry8 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 123,
ZipEntry::STORED, 100000)
assert_equals(entry1, entry1)
assert_equals(entry1, entry2)
assert(entry2 != entry3)
assert(entry3 != entry4)
assert(entry4 != entry5)
assert(entry5 != entry6)
assert(entry6 != entry7)
assert(entry7 != entry8)
assert(entry7 != "hello")
assert(entry7 != 12)
end
end
module IOizeString
attr_reader :tell
def read(count = nil)
@tell ||= 0
count = size unless count
retVal = slice(@tell, count)
@tell += count
return retVal
end
def seek(index, offset)
@tell ||= 0
case offset
when IO::SEEK_END
newPos = size + index
when IO::SEEK_SET
newPos = index
when IO::SEEK_CUR
newPos = @tell + index
else
raise "Error in test method IOizeString::seek"
end
if (newPos < 0 || newPos >= size)
raise Errno::EINVAL
else
@tell=newPos
end
end
def reset
@tell = 0
end
end
class ZipLocalEntryTest < RUNIT::TestCase
def test_readLocalEntryHeaderOfFirstTestZipEntry
File.open(TestZipFile::TEST_ZIP3.zipName) {
|file|
entry = ZipEntry.readLocalEntry(file)
assert_equal("", entry.comment)
# Differs from windows and unix because of CR LF
# assert_equal(480, entry.compressedSize)
# assert_equal(0x2a27930f, entry.crc)
# extra field is 21 bytes long
# probably contains some unix attrutes or something
# disabled: assert_equal(nil, entry.extra)
assert_equal(ZipEntry::DEFLATED, entry.compressionMethod)
assert_equal(TestZipFile::TEST_ZIP3.entryNames[0], entry.name)
assert_equal(File.size(TestZipFile::TEST_ZIP3.entryNames[0]), entry.size)
assert(! entry.isDirectory)
}
end
def test_readLocalEntryFromNonZipFile
File.open("ziptest.rb") {
|file|
assert_equals(nil, ZipEntry.readLocalEntry(file))
}
end
def test_readLocalEntryFromTruncatedZipFile
zipFragment=""
File.open(TestZipFile::TEST_ZIP2.zipName) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
zipFragment.extend(IOizeString).reset
entry = ZipEntry.new
entry.readLocalEntry(zipFragment)
fail "ZipError expected"
rescue ZipError
end
def test_writeEntry
entry = ZipEntry.new("file.zip", "entryName", "my little comment",
"thisIsSomeExtraInformation", 100, 987654,
ZipEntry::DEFLATED, 400)
writeToFile("localEntryHeader.bin", "centralEntryHeader.bin", entry)
entryReadLocal, entryReadCentral = readFromFile("localEntryHeader.bin", "centralEntryHeader.bin")
compareLocalEntryHeaders(entry, entryReadLocal)
compareCDirEntryHeaders(entry, entryReadCentral)
end
private
def compareLocalEntryHeaders(entry1, entry2)
assert_equals(entry1.compressedSize , entry2.compressedSize)
assert_equals(entry1.crc , entry2.crc)
assert_equals(entry1.extra , entry2.extra)
assert_equals(entry1.compressionMethod, entry2.compressionMethod)
assert_equals(entry1.name , entry2.name)
assert_equals(entry1.size , entry2.size)
assert_equals(entry1.localHeaderOffset, entry2.localHeaderOffset)
end
def compareCDirEntryHeaders(entry1, entry2)
compareLocalEntryHeaders(entry1, entry2)
assert_equals(entry1.comment, entry2.comment)
end
def writeToFile(localFileName, centralFileName, entry)
File.open(localFileName, "wb") { |f| entry.writeLocalEntry(f) }
File.open(centralFileName, "wb") { |f| entry.writeCDirEntry(f) }
end
def readFromFile(localFileName, centralFileName)
localEntry = nil
cdirEntry = nil
File.open(localFileName, "rb") { |f| localEntry = ZipEntry.readLocalEntry(f) }
File.open(centralFileName, "rb") { |f| cdirEntry = ZipEntry.readCDirEntry(f) }
return [localEntry, cdirEntry]
end
end
module DecompressorTests
# expects @refText and @decompressor
def test_readEverything
assert_equals(@refText, @decompressor.read)
end
def test_readInChunks
chunkSize = 5
while (decompressedChunk = @decompressor.read(chunkSize))
assert_equals(@refText.slice!(0, chunkSize), decompressedChunk)
end
assert_equals(0, @refText.size)
end
end
class InflaterTest < RUNIT::TestCase
include DecompressorTests
def setup
@file = File.new("file1.txt.deflatedData", "rb")
@refText=""
File.open("file1.txt") { |f| @refText = f.read }
@decompressor = Inflater.new(@file)
end
def teardown
@file.close
end
end
class PassThruDecompressorTest < RUNIT::TestCase
include DecompressorTests
TEST_FILE="file1.txt"
def setup
@file = File.new(TEST_FILE)
@refText=""
File.open(TEST_FILE) { |f| @refText = f.read }
@decompressor = PassThruDecompressor.new(@file, File.size(TEST_FILE))
end
def teardown
@file.close
end
end
module AssertEntry
def assertNextEntry(filename, zis)
assertEntry(filename, zis, zis.getNextEntry.name)
end
def assertEntry(filename, zis, entryName)
assert_equals(filename, entryName)
assertEntryContentsForStream(filename, zis, entryName)
end
def assertEntryContentsForStream(filename, zis, entryName)
File.open(filename, "rb") {
|file|
expected = file.read
actual = zis.read
if (expected != actual)
if (expected.length > 400 || actual.length > 400)
zipEntryFilename=entryName+".zipEntry"
File.open(zipEntryFilename, "wb") { |file| file << actual }
fail("File '#{filename}' is different from '#{zipEntryFilename}'")
else
assert_equals(expected, actual)
end
end
}
end
def AssertEntry.assertContents(filename, aString)
fileContents = ""
File.open(filename, "rb") { |f| fileContents = f.read }
if (fileContents != aString)
if (expected.length > 400 || actual.length > 400)
stringFile = filename + ".other"
File.open(stringFile, "wb") { |f| f << aString }
fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
else
assert_equals(expected, actual)
end
end
end
def assertStreamContents(zis, testZipFile)
assert(zis != nil)
testZipFile.entryNames.each {
|entryName|
assertNextEntry(entryName, zis)
}
assert_equals(nil, zis.getNextEntry)
end
def assertTestZipContents(testZipFile)
ZipInputStream.open(testZipFile.zipName) {
|zis|
assertStreamContents(zis, testZipFile)
}
end
def assertEntryContents(zipFile, entryName, filename = entryName.to_s)
zis = zipFile.getInputStream(entryName)
assertEntryContentsForStream(filename, zis, entryName)
ensure
zis.close if zis
end
end
class ZipInputStreamTest < RUNIT::TestCase
include AssertEntry
def test_new
zis = ZipInputStream.new(TestZipFile::TEST_ZIP2.zipName)
assertStreamContents(zis, TestZipFile::TEST_ZIP2)
zis.close
end
def test_openWithBlock
ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName) {
|zis|
assertStreamContents(zis, TestZipFile::TEST_ZIP2)
}
end
def test_openWithoutBlock
zis = ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName)
assertStreamContents(zis, TestZipFile::TEST_ZIP2)
end
def test_incompleteReads
ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName) {
|zis|
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[0], entry.name)
assert zis.gets.length > 0
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[1], entry.name)
assert_equals(0, entry.size)
assert_equals(nil, zis.gets)
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[2], entry.name)
assert zis.gets.length > 0
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[3], entry.name)
assert zis.gets.length > 0
}
end
end
class TestFiles
RANDOM_ASCII_FILE1 = "randomAscii1.txt"
RANDOM_ASCII_FILE2 = "randomAscii2.txt"
RANDOM_ASCII_FILE3 = "randomAscii3.txt"
RANDOM_BINARY_FILE1 = "randomBinary1.bin"
RANDOM_BINARY_FILE2 = "randomBinary2.bin"
EMPTY_TEST_DIR = "emptytestdir"
ASCII_TEST_FILES = [ RANDOM_ASCII_FILE1, RANDOM_ASCII_FILE2, RANDOM_ASCII_FILE3 ]
BINARY_TEST_FILES = [ RANDOM_BINARY_FILE1, RANDOM_BINARY_FILE2 ]
TEST_DIRECTORIES = [ EMPTY_TEST_DIR ]
TEST_FILES = [ ASCII_TEST_FILES, BINARY_TEST_FILES, EMPTY_TEST_DIR ].flatten!
def TestFiles.createTestFiles(recreate)
if (recreate ||
! (TEST_FILES.inject(true) { |accum, element| accum && File.exists?(element) }))
ASCII_TEST_FILES.each_with_index {
|filename, index|
createRandomAscii(filename, 1E4 * (index+1))
}
BINARY_TEST_FILES.each_with_index {
|filename, index|
createRandomBinary(filename, 1E4 * (index+1))
}
ensureDir(EMPTY_TEST_DIR)
end
end
private
def TestFiles.createRandomAscii(filename, size)
File.open(filename, "wb") {
|file|
while (file.tell < size)
file << rand
end
}
end
def TestFiles.createRandomBinary(filename, size)
File.open(filename, "wb") {
|file|
while (file.tell < size)
file << rand.to_a.pack("V")
end
}
end
def TestFiles.ensureDir(name)
if File.exists?(name)
return if File.stat(name).directory?
File.delete(name)
end
Dir.mkdir(name)
end
end
# For representation and creation of
# test data
class TestZipFile
attr_accessor :zipName, :entryNames, :comment
def initialize(zipName, entryNames, comment = "")
@zipName=zipName
@entryNames=entryNames
@comment = comment
end
def TestZipFile.createTestZips(recreate)
files = Dir.entries(".")
if (recreate ||
! (files.index(TEST_ZIP1.zipName) &&
files.index(TEST_ZIP2.zipName) &&
files.index(TEST_ZIP3.zipName) &&
files.index(TEST_ZIP4.zipName) &&
files.index("empty.txt") &&
files.index("short.txt") &&
files.index("longAscii.txt") &&
files.index("longBinary.bin") ))
raise "failed to create test zip '#{TEST_ZIP1.zipName}'" unless
system("zip #{TEST_ZIP1.zipName} ziptest.rb")
raise "failed to remove entry from '#{TEST_ZIP1.zipName}'" unless
system("zip #{TEST_ZIP1.zipName} -d ziptest.rb")
File.open("empty.txt", "w") {}
File.open("short.txt", "w") { |file| file << "ABCDEF" }
ziptestTxt=""
File.open("ziptest.rb") { |file| ziptestTxt=file.read }
File.open("longAscii.txt", "w") {
|file|
while (file.tell < 1E5)
file << ziptestTxt
end
}
testBinaryPattern=""
File.open("empty.zip") { |file| testBinaryPattern=file.read }
testBinaryPattern *= 4
File.open("longBinary.bin", "wb") {
|file|
while (file.tell < 3E5)
file << testBinaryPattern << rand
end
}
raise "failed to create test zip '#{TEST_ZIP2.zipName}'" unless
system("zip #{TEST_ZIP2.zipName} #{TEST_ZIP2.entryNames.join(' ')}")
# without bash system interprets everything after echo as parameters to
# echo including | zip -z ...
raise "failed to add comment to test zip '#{TEST_ZIP2.zipName}'" unless
system("bash -c \"echo #{TEST_ZIP2.comment} | zip -z #{TEST_ZIP2.zipName}\"")
raise "failed to create test zip '#{TEST_ZIP3.zipName}'" unless
system("zip #{TEST_ZIP3.zipName} #{TEST_ZIP3.entryNames.join(' ')}")
raise "failed to create test zip '#{TEST_ZIP4.zipName}'" unless
system("zip #{TEST_ZIP4.zipName} #{TEST_ZIP4.entryNames.join(' ')}")
end
rescue
raise $!.to_s +
"\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" +
"to create test data. If you don't have it you can download\n" +
"the necessary test files at http://sf.net/projects/rubyzip."
end
TEST_ZIP1 = TestZipFile.new("empty.zip", [])
TEST_ZIP2 = TestZipFile.new("4entry.zip", %w{ longAscii.txt empty.txt short.txt longBinary.bin},
"my zip comment")
TEST_ZIP3 = TestZipFile.new("test1.zip", %w{ file1.txt })
TEST_ZIP4 = TestZipFile.new("zipWithDir.zip", [ "file1.txt",
TestFiles::EMPTY_TEST_DIR])
end
class AbstractOutputStreamTest < RUNIT::TestCase
class TestOutputStream
include AbstractOutputStream
attr_accessor :buffer
def initialize
@buffer = ""
end
def << (data)
@buffer << data
self
end
end
def setup
@outputStream = TestOutputStream.new
@origCommaSep = $,
@origOutputSep = $\
end
def teardown
$, = @origCommaSep
$\ = @origOutputSep
end
def test_write
count = @outputStream.write("a little string")
assert_equals("a little string", @outputStream.buffer)
assert_equals("a little string".length, count)
count = @outputStream.write(". a little more")
assert_equals("a little string. a little more", @outputStream.buffer)
assert_equals(". a little more".length, count)
end
def test_print
$\ = nil # record separator set to nil
@outputStream.print("hello")
assert_equals("hello", @outputStream.buffer)
@outputStream.print(" world.")
assert_equals("hello world.", @outputStream.buffer)
@outputStream.print(" You ok ", "out ", "there?")
assert_equals("hello world. You ok out there?", @outputStream.buffer)
$\ = "\n"
@outputStream.print
assert_equals("hello world. You ok out there?\n", @outputStream.buffer)
@outputStream.print("I sure hope so!")
assert_equals("hello world. You ok out there?\nI sure hope so!\n", @outputStream.buffer)
$, = "X"
@outputStream.buffer = ""
@outputStream.print("monkey", "duck", "zebra")
assert_equals("monkeyXduckXzebra\n", @outputStream.buffer)
$\ = nil
@outputStream.buffer = ""
@outputStream.print(20)
assert_equals("20", @outputStream.buffer)
end
def test_printf
@outputStream.printf("%d %04x", 123, 123)
assert_equals("123 007b", @outputStream.buffer)
end
def test_putc
@outputStream.putc("A")
assert_equals("A", @outputStream.buffer)
@outputStream.putc(65)
assert_equals("AA", @outputStream.buffer)
end
def test_puts
@outputStream.puts
assert_equals("\n", @outputStream.buffer)
@outputStream.puts("hello", "world")
assert_equals("\nhello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts("hello\n", "world\n")
assert_equals("hello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(["hello\n", "world\n"])
assert_equals("hello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(["hello\n", "world\n"], "bingo")
assert_equals("hello\nworld\nbingo\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(16, 20, 50, "hello")
assert_equals("16\n20\n50\nhello\n", @outputStream.buffer)
end
end
module CrcTest
def runCrcTest(compressorClass)
str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
fakeOut = AbstractOutputStreamTest::TestOutputStream.new
deflater = compressorClass.new(fakeOut)
deflater << str
assert_equals(0x919920fc, deflater.crc)
end
end
class PassThruCompressorTest < RUNIT::TestCase
include CrcTest
def test_size
File.open("dummy.txt", "wb") {
|file|
compressor = PassThruCompressor.new(file)
assert_equals(0, compressor.size)
t1 = "hello world"
t2 = ""
t3 = "bingo"
compressor << t1
assert_equals(compressor.size, t1.size)
compressor << t2
assert_equals(compressor.size, t1.size + t2.size)
compressor << t3
assert_equals(compressor.size, t1.size + t2.size + t3.size)
}
end
def test_crc
runCrcTest(PassThruCompressor)
end
end
class DeflaterTest < RUNIT::TestCase
include CrcTest
def test_outputOperator
txt = loadFile("ziptest.rb")
deflate(txt, "deflatertest.bin")
inflatedTxt = inflate("deflatertest.bin")
assert_equals(txt, inflatedTxt)
end
private
def loadFile(fileName)
txt = nil
File.open(fileName, "rb") { |f| txt = f.read }
end
def deflate(data, fileName)
File.open(fileName, "wb") {
|file|
deflater = Deflater.new(file)
deflater << data
deflater.finish
assert_equals(deflater.size, data.size)
file << "trailing data for zlib with -MAX_WBITS"
}
end
def inflate(fileName)
txt = nil
File.open(fileName, "rb") {
|file|
inflater = Inflater.new(file)
txt = inflater.read
}
end
def test_crc
runCrcTest(Deflater)
end
end
class ZipOutputStreamTest < RUNIT::TestCase
include AssertEntry
TEST_ZIP = TestZipFile::TEST_ZIP2.clone
TEST_ZIP.zipName = "output.zip"
def test_new
zos = ZipOutputStream.new(TEST_ZIP.zipName)
zos.comment = TEST_ZIP.comment
writeTestZip(zos)
zos.close
assertTestZipContents(TEST_ZIP)
end
def test_open
ZipOutputStream.open(TEST_ZIP.zipName) {
|zos|
zos.comment = TEST_ZIP.comment
writeTestZip(zos)
}
assertTestZipContents(TEST_ZIP)
end
def test_writingToClosedStream
assertIOErrorInClosedStream { |zos| zos << "hello world" }
assertIOErrorInClosedStream { |zos| zos.puts "hello world" }
assertIOErrorInClosedStream { |zos| zos.write "hello world" }
end
def test_cannotOpenFile
name = TestFiles::EMPTY_TEST_DIR
begin
zos = ZipOutputStream.open(name)
rescue Exception
assert($!.kind_of?(Errno::EISDIR) || # Linux
$!.kind_of?(Errno::EEXIST) || # Windows/cygwin
$!.kind_of?(Errno::EACCES), # Windows
"Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.type}")
end
end
def assertIOErrorInClosedStream
assert_exception(IOError) {
zos = ZipOutputStream.new("test_putOnClosedStream.zip")
zos.close
yield zos
}
end
def writeTestZip(zos)
TEST_ZIP.entryNames.each {
|entryName|
zos.putNextEntry(entryName)
File.open(entryName, "rb") { |f| zos.write(f.read) }
}
end
end
module Enumerable
def compareEnumerables(otherEnumerable)
otherAsArray = otherEnumerable.to_a
index=0
each_with_index {
|element, index|
return false unless yield(element, otherAsArray[index])
}
return index+1 == otherAsArray.size
end
end
class ZipCentralDirectoryEntryTest < RUNIT::TestCase
def test_readFromStream
File.open("testDirectory.bin", "rb") {
|file|
entry = ZipEntry.readCDirEntry(file)
assert_equals("longAscii.txt", entry.name)
assert_equals(ZipEntry::DEFLATED, entry.compressionMethod)
assert_equals(106490, entry.size)
assert_equals(3784, entry.compressedSize)
assert_equals(0xfcd1799c, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals("empty.txt", entry.name)
assert_equals(ZipEntry::STORED, entry.compressionMethod)
assert_equals(0, entry.size)
assert_equals(0, entry.compressedSize)
assert_equals(0x0, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals("short.txt", entry.name)
assert_equals(ZipEntry::STORED, entry.compressionMethod)
assert_equals(6, entry.size)
assert_equals(6, entry.compressedSize)
assert_equals(0xbb76fe69, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals("longBinary.bin", entry.name)
assert_equals(ZipEntry::DEFLATED, entry.compressionMethod)
assert_equals(1000024, entry.size)
assert_equals(70847, entry.compressedSize)
assert_equals(0x10da7d59, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals(nil, entry)
# Fields that are not check by this test:
# version made by 2 bytes
# version needed to extract 2 bytes
# general purpose bit flag 2 bytes
# last mod file time 2 bytes
# last mod file date 2 bytes
# compressed size 4 bytes
# uncompressed size 4 bytes
# disk number start 2 bytes
# internal file attributes 2 bytes
# external file attributes 4 bytes
# relative offset of local header 4 bytes
# file name (variable size)
# extra field (variable size)
# file comment (variable size)
}
end
def test_ReadEntryFromTruncatedZipFile
fragment=""
File.open("testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
fragment.extend(IOizeString)
entry = ZipEntry.new
entry.readCDirEntry(fragment)
fail "ZipError expected"
rescue ZipError
end
end
class ZipCentralDirectoryTest < RUNIT::TestCase
def test_readFromStream
File.open(TestZipFile::TEST_ZIP2.zipName, "rb") {
|zipFile|
cdir = ZipCentralDirectory.readFromStream(zipFile)
assert_equals(TestZipFile::TEST_ZIP2.entryNames.size, cdir.size)
assert(cdir.compareEnumerables(TestZipFile::TEST_ZIP2.entryNames) {
|cdirEntry, testEntryName|
cdirEntry.name == testEntryName
})
assert_equals(TestZipFile::TEST_ZIP2.comment, cdir.comment)
}
end
def test_readFromInvalidStream
File.open("ziptest.rb", "rb") {
|zipFile|
cdir = ZipCentralDirectory.new
cdir.readFromStream(zipFile)
}
fail "ZipError expected!"
rescue ZipError
end
def test_ReadFromTruncatedZipFile
fragment=""
File.open("testDirectory.bin") { |f| fragment = f.read }
fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
fragment.extend(IOizeString)
entry = ZipCentralDirectory.new
entry.readFromStream(fragment)
fail "ZipError expected"
rescue ZipError
end
def test_writeToStream
entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
cdir = ZipCentralDirectory.new(entries, "my zip comment")
File.open("cdirtest.bin", "wb") { |f| cdir.writeToStream(f) }
cdirReadback = ZipCentralDirectory.new
File.open("cdirtest.bin", "rb") { |f| cdirReadback.readFromStream(f) }
assert_equals(cdir.entries, cdirReadback.entries)
end
def test_equality
cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"my zip comment")
cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"my zip comment")
cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"comment?")
cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"comment?")
assert_equals(cdir1, cdir1)
assert_equals(cdir1, cdir2)
assert(cdir1 != cdir3)
assert(cdir2 != cdir3)
assert(cdir2 != cdir3)
assert(cdir3 != cdir4)
assert(cdir3 != "hello")
end
end
class BasicZipFileTest < RUNIT::TestCase
include AssertEntry
def setup
@zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zipName)
@testEntryNameIndex=0
end
def nextTestEntryName
retVal=TestZipFile::TEST_ZIP2.entryNames[@testEntryNameIndex]
@testEntryNameIndex+=1
return retVal
end
def test_entries
assert_equals(TestZipFile::TEST_ZIP2.entryNames, @zipFile.entries.map {|e| e.name} )
end
def test_each
@zipFile.each {
|entry|
assert_equals(nextTestEntryName, entry.name)
}
assert_equals(4, @testEntryNameIndex)
end
def test_foreach
ZipFile.foreach(TestZipFile::TEST_ZIP2.zipName) {
|entry|
assert_equals(nextTestEntryName, entry.name)
}
assert_equals(4, @testEntryNameIndex)
end
def test_getInputStream
@zipFile.each {
|entry|
assertEntry(nextTestEntryName, @zipFile.getInputStream(entry),
entry.name)
}
assert_equals(4, @testEntryNameIndex)
end
def test_getInputStreamBlock
fileAndEntryName = @zipFile.entries.first.name
@zipFile.getInputStream(fileAndEntryName) {
|zis|
assertEntryContentsForStream(fileAndEntryName,
zis,
fileAndEntryName)
}
end
end
class CommonZipFileFixture < RUNIT::TestCase
include AssertEntry
EMPTY_FILENAME = "emptyZipFile.zip"
TEST_ZIP = TestZipFile::TEST_ZIP2.clone
TEST_ZIP.zipName = "4entry_copy.zip"
def setup
File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
File.copy(TestZipFile::TEST_ZIP2.zipName, TEST_ZIP.zipName)
end
end
class ZipFileTest < CommonZipFileFixture
def test_createFromScratch
comment = "a short comment"
zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
zf.comment = comment
zf.close
zfRead = ZipFile.new(EMPTY_FILENAME)
assert_equals(comment, zfRead.comment)
assert_equals(0, zfRead.entries.length)
end
def test_add
srcFile = "ziptest.rb"
entryName = "newEntryName.rb"
assert(File.exists? srcFile)
zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
zf.add(entryName, srcFile)
zf.close
zfRead = ZipFile.new(EMPTY_FILENAME)
assert_equals("", zfRead.comment)
assert_equals(1, zfRead.entries.length)
assert_equals(entryName, zfRead.entries.first.name)
AssertEntry.assertContents(srcFile,
zfRead.getInputStream(entryName) { |zis| zis.read })
end
def test_addExistingEntryName
assert_exception(ZipEntryExistsError) {
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.add(zf.entries.first.name, "ziptest.rb")
}
}
end
def test_addExistingEntryNameReplace
gotCalled = false
replacedEntry = nil
ZipFile.open(TEST_ZIP.zipName) {
|zf|
replacedEntry = zf.entries.first.name
zf.add(replacedEntry, "ziptest.rb") { gotCalled = true; true }
}
assert(gotCalled)
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assertContains(zf, replacedEntry, "ziptest.rb")
}
end
def test_addDirectory
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
}
ZipFile.open(TEST_ZIP.zipName) {
|zf|
dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
assert(dirEntry.isDirectory)
}
end
def test_remove
entryToRemove, *remainingEntries = TEST_ZIP.entryNames
File.copy(TestZipFile::TEST_ZIP2.zipName, TEST_ZIP.zipName)
zf = ZipFile.new(TEST_ZIP.zipName)
assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
zf.remove(entryToRemove)
assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
assert_equals(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
zf.close
zfRead = ZipFile.new(TEST_ZIP.zipName)
assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
assert_equals(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
zfRead.close
end
def test_rename
entryToRename, *remainingEntries = TEST_ZIP.entryNames
zf = ZipFile.new(TEST_ZIP.zipName)
assert(zf.entries.map { |e| e.name }.include? entryToRename)
newName = "changed name"
assert(! zf.entries.map { |e| e.name }.include?(newName))
zf.rename(entryToRename, newName)
assert(zf.entries.map { |e| e.name }.include? newName)
zf.close
zfRead = ZipFile.new(TEST_ZIP.zipName)
assert(zfRead.entries.map { |e| e.name }.include? newName)
zfRead.close
end
def test_renameToExistingEntry
oldEntries = nil
ZipFile.open(TEST_ZIP.zipName) { |zf| oldEntries = zf.entries }
assert_exception(ZipEntryExistsError) {
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.rename(zf.entries[0], zf.entries[1].name)
}
}
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assert_equals(oldEntries.map{ |e| e.name }, zf.entries.map{ |e| e.name })
}
end
def test_renameToExistingEntryOverwrite
oldEntries = nil
ZipFile.open(TEST_ZIP.zipName) { |zf| oldEntries = zf.entries }
gotCalled = false
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
}
assert(gotCalled)
oldEntries.delete_at(0)
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assert_equals(oldEntries.map{ |e| e.name },
zf.entries.map{ |e| e.name })
}
end
def test_renameNonEntry
nonEntry = "bogusEntry"
targetEntry = "targetEntryName"
zf = ZipFile.new(TEST_ZIP.zipName)
assert(! zf.entries.include?(nonEntry))
assert_exception(ZipNoSuchEntryError) {
zf.rename(nonEntry, targetEntry)
}
zf.commit
assert(! zf.entries.include?(targetEntry))
ensure
zf.close
end
def test_renameEntryToExistingEntry
entry1, entry2, *remaining = TEST_ZIP.entryNames
zf = ZipFile.new(TEST_ZIP.zipName)
assert_exception(ZipEntryExistsError) {
zf.rename(entry1, entry2)
}
ensure
zf.close
end
def test_replace
unchangedEntries = TEST_ZIP.entryNames.dup
entryToReplace = unchangedEntries.delete_at(2)
newEntrySrcFilename = "ziptest.rb"
zf = ZipFile.new(TEST_ZIP.zipName)
zf.replace(entryToReplace, newEntrySrcFilename)
zf.close
zfRead = ZipFile.new(TEST_ZIP.zipName)
AssertEntry::assertContents(newEntrySrcFilename,
zfRead.getInputStream(entryToReplace) { |is| is.read })
zfRead.close
end
def test_replaceNonEntry
entryToReplace = "nonExistingEntryname"
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assert_exception(ZipNoSuchEntryError) {
zf.replace(entryToReplace, "ziptest.rb")
}
}
end
def test_commit
newName = "renamedFirst"
zf = ZipFile.new(TEST_ZIP.zipName)
oldName = zf.entries.first
zf.rename(oldName, newName)
zf.commit
zfRead = ZipFile.new(TEST_ZIP.zipName)
assert(zfRead.entries.detect { |e| e.name == newName } != nil)
assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
zfRead.close
zf.close
end
# This test tests that after commit, you
# can delete the file you used to add the entry to the zip file
# with
def test_commitUseZipEntry
File.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
zf = ZipFile.open(TEST_ZIP.zipName)
zf.add("okToDelete.txt", "okToDelete.txt")
assertContains(zf, "okToDelete.txt")
zf.commit
File.move("okToDelete.txt", "okToDeleteMoved.txt")
assertContains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
end
# def test_close
# zf = ZipFile.new(TEST_ZIP.zipName)
# zf.close
# assert_exception(IOError) {
# zf.extract(TEST_ZIP.entryNames.first, "hullubullu")
# }
# end
def test_compound1
renamedName = "renamedName"
originalEntries = []
begin
zf = ZipFile.new(TEST_ZIP.zipName)
originalEntries = zf.entries.dup
assertNotContains(zf, TestFiles::RANDOM_ASCII_FILE1)
zf.add(TestFiles::RANDOM_ASCII_FILE1,
TestFiles::RANDOM_ASCII_FILE1)
assertContains(zf, TestFiles::RANDOM_ASCII_FILE1)
zf.rename(zf.entries[0], renamedName)
assertContains(zf, renamedName)
TestFiles::BINARY_TEST_FILES.each {
|filename|
zf.add(filename, filename)
assertContains(zf, filename)
}
assertContains(zf, originalEntries.last.to_s)
zf.remove(originalEntries.last.to_s)
assertNotContains(zf, originalEntries.last.to_s)
ensure
zf.close
end
begin
zfRead = ZipFile.new(TEST_ZIP.zipName)
assertContains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
assertContains(zfRead, renamedName)
TestFiles::BINARY_TEST_FILES.each {
|filename|
assertContains(zfRead, filename)
}
assertNotContains(zfRead, originalEntries.last.to_s)
ensure
zfRead.close
end
end
def test_compound2
begin
zf = ZipFile.new(TEST_ZIP.zipName)
originalEntries = zf.entries.dup
originalEntries.each {
|entry|
zf.remove(entry)
assertNotContains(zf, entry)
}
assert(zf.entries.empty?)
TestFiles::ASCII_TEST_FILES.each {
|filename|
zf.add(filename, filename)
assertContains(zf, filename)
}
assert_equals(zf.entries.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
assertNotContains(zf, TestFiles::ASCII_TEST_FILES[0])
assertContains(zf, "newName")
ensure
zf.close
end
begin
zfRead = ZipFile.new(TEST_ZIP.zipName)
asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
asciiTestFiles.shift
asciiTestFiles.each {
|filename|
assertContains(zf, filename)
}
assertContains(zf, "newName")
ensure
zfRead.close
end
end
private
def assertContains(zf, entryName, filename = entryName)
assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
assertEntryContents(zf, entryName, filename) if File.exists?(filename)
end
def assertNotContains(zf, entryName)
assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
end
end
class ZipFileExtractTest < CommonZipFileFixture
EXTRACTED_FILENAME = "extEntry"
ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entryNames.reverse
def setup
super
File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
end
def test_extract
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
assert(File.exists? EXTRACTED_FILENAME)
AssertEntry::assertContents(EXTRACTED_FILENAME,
zf.getInputStream(ENTRY_TO_EXTRACT) { |is| is.read })
}
end
def test_extractExists
writtenText = "written text"
File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
assert_exception(ZipDestinationFileExistsError) {
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.extract(zf.entries.first, EXTRACTED_FILENAME)
}
}
File.open(EXTRACTED_FILENAME, "r") {
|f|
assert_equals(writtenText, f.read)
}
end
def test_extractExistsOverwrite
writtenText = "written text"
File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
gotCalled = false
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.extract(zf.entries.first, EXTRACTED_FILENAME) { gotCalled = true; true }
}
assert(gotCalled)
File.open(EXTRACTED_FILENAME, "r") {
|f|
assert(writtenText != f.read)
}
end
def test_extractNonEntry
zf = ZipFile.new(TEST_ZIP.zipName)
assert_exception(ZipNoSuchEntryError) { zf.extract("nonExistingEntry", "nonExistingEntry") }
ensure
zf.close if zf
end
def test_extractNonEntry2
outFile = "outfile"
assert_exception(ZipNoSuchEntryError) {
zf = ZipFile.new(TEST_ZIP.zipName)
nonEntry = "hotdog-diddelidoo"
assert(! zf.entries.include?(nonEntry))
zf.extract(nonEntry, outFile)
zf.close
}
assert(! File.exists?(outFile))
end
end
class ZipFileExtractDirectoryTest < CommonZipFileFixture
TEST_OUT_NAME = "emptyOutDir"
def openZip(&aProc)
assert(aProc != nil)
ZipFile.open(TestZipFile::TEST_ZIP4.zipName, &aProc)
end
def extractTestDir(&aProc)
openZip {
|zf|
zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
}
end
def setup
super
Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
end
def test_extractDirectory
extractTestDir
assert(File.directory? TEST_OUT_NAME)
end
def test_extractDirectoryExistsAsDir
Dir.mkdir TEST_OUT_NAME
extractTestDir
assert(File.directory? TEST_OUT_NAME)
end
def test_extractDirectoryExistsAsFile
File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
assert_exception(ZipDestinationFileExistsError) { extractTestDir }
end
def test_extractDirectoryExistsAsFileOverwrite
File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
gotCalled = false
extractTestDir {
|entry, destPath|
gotCalled = true
assert_equals(TEST_OUT_NAME, destPath)
assert(entry.isDirectory)
true
}
assert(gotCalled)
assert(File.directory? TEST_OUT_NAME)
end
end
TestFiles::createTestFiles(ARGV.index("recreate") != nil ||
ARGV.index("recreateonly") != nil)
TestZipFile::createTestZips(ARGV.index("recreate") != nil ||
ARGV.index("recreateonly") != nil)
exit if ARGV.index("recreateonly") != nil
#require 'runit/cui/testrunner'
#RUNIT::CUI::TestRunner.run(ZipFileTest.suite)
# Copyright (C) 2002 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.
#!/usr/bin/env ruby
$VERBOSE = true
require 'rubyunit'
require 'zip'
include Zip
Dir.chdir "test"
class AbstractInputStreamTest < RUNIT::TestCase
# AbstractInputStream subclass that provides a read method
TEST_LINES = [ "Hello world#{$/}",
"this is the second line#{$/}",
"this is the last line"]
TEST_STRING = TEST_LINES.join
class TestAbstractInputStream
include AbstractInputStream
def initialize(aString)
@contents = aString
@readPointer = 0
end
def read(charsToRead)
retVal=@contents[@readPointer, charsToRead]
@readPointer+=charsToRead
return retVal
end
def produceInput
read(100)
end
def inputFinished?
@contents[@readPointer] == nil
end
end
def setup
@io = TestAbstractInputStream.new(TEST_STRING)
end
def test_gets
assert_equals(TEST_LINES[0], @io.gets)
assert_equals(TEST_LINES[1], @io.gets)
assert_equals(TEST_LINES[2], @io.gets)
assert_equals(nil, @io.gets)
end
def test_getsMultiCharSeperator
assert_equals("Hell", @io.gets("ll"))
assert_equals("o world#{$/}this is the second l", @io.gets("d l"))
end
def test_each_line
lineNumber=0
@io.each_line {
|line|
assert_equals(TEST_LINES[lineNumber], line)
lineNumber+=1
}
end
def test_readlines
assert_equals(TEST_LINES, @io.readlines)
end
def test_readline
test_gets
begin
@io.readline
fail "EOFError expected"
rescue EOFError
end
end
end
class ZipEntryTest < RUNIT::TestCase
TEST_ZIPFILE = "someZipFile.zip"
TEST_COMMENT = "a comment"
TEST_COMPRESSED_SIZE = 1234
TEST_CRC = 325324
TEST_EXTRA = "Some data here"
TEST_COMPRESSIONMETHOD = ZipEntry::DEFLATED
TEST_NAME = "entry name"
TEST_SIZE = 8432
TEST_ISDIRECTORY = false
def test_constructorAndGetters
entry = ZipEntry.new(TEST_ZIPFILE,
TEST_NAME,
TEST_COMMENT,
TEST_EXTRA,
TEST_COMPRESSED_SIZE,
TEST_CRC,
TEST_COMPRESSIONMETHOD,
TEST_SIZE)
assert_equals(TEST_COMMENT, entry.comment)
assert_equals(TEST_COMPRESSED_SIZE, entry.compressedSize)
assert_equals(TEST_CRC, entry.crc)
assert_equals(TEST_EXTRA, entry.extra)
assert_equals(TEST_COMPRESSIONMETHOD, entry.compressionMethod)
assert_equals(TEST_NAME, entry.name)
assert_equals(TEST_SIZE, entry.size)
assert_equals(TEST_ISDIRECTORY, entry.isDirectory)
end
def test_equality
entry1 = ZipEntry.new("file.zip", "name", "isNotCompared",
"something extra", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry2 = ZipEntry.new("file.zip", "name", "isNotComparedXXX",
"something extra", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry3 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extra", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry4 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 123, 1234,
ZipEntry::DEFLATED, 10000)
entry5 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 1234,
ZipEntry::DEFLATED, 10000)
entry6 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 123,
ZipEntry::DEFLATED, 10000)
entry7 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 123,
ZipEntry::STORED, 10000)
entry8 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
"something extraXX", 12, 123,
ZipEntry::STORED, 100000)
assert_equals(entry1, entry1)
assert_equals(entry1, entry2)
assert(entry2 != entry3)
assert(entry3 != entry4)
assert(entry4 != entry5)
assert(entry5 != entry6)
assert(entry6 != entry7)
assert(entry7 != entry8)
assert(entry7 != "hello")
assert(entry7 != 12)
end
end
module IOizeString
attr_reader :tell
def read(count = nil)
@tell ||= 0
count = size unless count
retVal = slice(@tell, count)
@tell += count
return retVal
end
def seek(index, offset)
@tell ||= 0
case offset
when IO::SEEK_END
newPos = size + index
when IO::SEEK_SET
newPos = index
when IO::SEEK_CUR
newPos = @tell + index
else
raise "Error in test method IOizeString::seek"
end
if (newPos < 0 || newPos >= size)
raise Errno::EINVAL
else
@tell=newPos
end
end
def reset
@tell = 0
end
end
class ZipLocalEntryTest < RUNIT::TestCase
def test_readLocalEntryHeaderOfFirstTestZipEntry
File.open(TestZipFile::TEST_ZIP3.zipName) {
|file|
entry = ZipEntry.readLocalEntry(file)
assert_equal("", entry.comment)
# Differs from windows and unix because of CR LF
# assert_equal(480, entry.compressedSize)
# assert_equal(0x2a27930f, entry.crc)
# extra field is 21 bytes long
# probably contains some unix attrutes or something
# disabled: assert_equal(nil, entry.extra)
assert_equal(ZipEntry::DEFLATED, entry.compressionMethod)
assert_equal(TestZipFile::TEST_ZIP3.entryNames[0], entry.name)
assert_equal(File.size(TestZipFile::TEST_ZIP3.entryNames[0]), entry.size)
assert(! entry.isDirectory)
}
end
def test_readLocalEntryFromNonZipFile
File.open("ziptest.rb") {
|file|
assert_equals(nil, ZipEntry.readLocalEntry(file))
}
end
def test_readLocalEntryFromTruncatedZipFile
zipFragment=""
File.open(TestZipFile::TEST_ZIP2.zipName) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
zipFragment.extend(IOizeString).reset
entry = ZipEntry.new
entry.readLocalEntry(zipFragment)
fail "ZipError expected"
rescue ZipError
end
def test_writeEntry
entry = ZipEntry.new("file.zip", "entryName", "my little comment",
"thisIsSomeExtraInformation", 100, 987654,
ZipEntry::DEFLATED, 400)
writeToFile("localEntryHeader.bin", "centralEntryHeader.bin", entry)
entryReadLocal, entryReadCentral = readFromFile("localEntryHeader.bin", "centralEntryHeader.bin")
compareLocalEntryHeaders(entry, entryReadLocal)
compareCDirEntryHeaders(entry, entryReadCentral)
end
private
def compareLocalEntryHeaders(entry1, entry2)
assert_equals(entry1.compressedSize , entry2.compressedSize)
assert_equals(entry1.crc , entry2.crc)
assert_equals(entry1.extra , entry2.extra)
assert_equals(entry1.compressionMethod, entry2.compressionMethod)
assert_equals(entry1.name , entry2.name)
assert_equals(entry1.size , entry2.size)
assert_equals(entry1.localHeaderOffset, entry2.localHeaderOffset)
end
def compareCDirEntryHeaders(entry1, entry2)
compareLocalEntryHeaders(entry1, entry2)
assert_equals(entry1.comment, entry2.comment)
end
def writeToFile(localFileName, centralFileName, entry)
File.open(localFileName, "wb") { |f| entry.writeLocalEntry(f) }
File.open(centralFileName, "wb") { |f| entry.writeCDirEntry(f) }
end
def readFromFile(localFileName, centralFileName)
localEntry = nil
cdirEntry = nil
File.open(localFileName, "rb") { |f| localEntry = ZipEntry.readLocalEntry(f) }
File.open(centralFileName, "rb") { |f| cdirEntry = ZipEntry.readCDirEntry(f) }
return [localEntry, cdirEntry]
end
end
module DecompressorTests
# expects @refText and @decompressor
def test_readEverything
assert_equals(@refText, @decompressor.read)
end
def test_readInChunks
chunkSize = 5
while (decompressedChunk = @decompressor.read(chunkSize))
assert_equals(@refText.slice!(0, chunkSize), decompressedChunk)
end
assert_equals(0, @refText.size)
end
end
class InflaterTest < RUNIT::TestCase
include DecompressorTests
def setup
@file = File.new("file1.txt.deflatedData", "rb")
@refText=""
File.open("file1.txt") { |f| @refText = f.read }
@decompressor = Inflater.new(@file)
end
def teardown
@file.close
end
end
class PassThruDecompressorTest < RUNIT::TestCase
include DecompressorTests
TEST_FILE="file1.txt"
def setup
@file = File.new(TEST_FILE)
@refText=""
File.open(TEST_FILE) { |f| @refText = f.read }
@decompressor = PassThruDecompressor.new(@file, File.size(TEST_FILE))
end
def teardown
@file.close
end
end
module AssertEntry
def assertNextEntry(filename, zis)
assertEntry(filename, zis, zis.getNextEntry.name)
end
def assertEntry(filename, zis, entryName)
assert_equals(filename, entryName)
assertEntryContentsForStream(filename, zis, entryName)
end
def assertEntryContentsForStream(filename, zis, entryName)
File.open(filename, "rb") {
|file|
expected = file.read
actual = zis.read
if (expected != actual)
if (expected.length > 400 || actual.length > 400)
zipEntryFilename=entryName+".zipEntry"
File.open(zipEntryFilename, "wb") { |file| file << actual }
fail("File '#{filename}' is different from '#{zipEntryFilename}'")
else
assert_equals(expected, actual)
end
end
}
end
def AssertEntry.assertContents(filename, aString)
fileContents = ""
File.open(filename, "rb") { |f| fileContents = f.read }
if (fileContents != aString)
if (expected.length > 400 || actual.length > 400)
stringFile = filename + ".other"
File.open(stringFile, "wb") { |f| f << aString }
fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
else
assert_equals(expected, actual)
end
end
end
def assertStreamContents(zis, testZipFile)
assert(zis != nil)
testZipFile.entryNames.each {
|entryName|
assertNextEntry(entryName, zis)
}
assert_equals(nil, zis.getNextEntry)
end
def assertTestZipContents(testZipFile)
ZipInputStream.open(testZipFile.zipName) {
|zis|
assertStreamContents(zis, testZipFile)
}
end
def assertEntryContents(zipFile, entryName, filename = entryName.to_s)
zis = zipFile.getInputStream(entryName)
assertEntryContentsForStream(filename, zis, entryName)
ensure
zis.close if zis
end
end
class ZipInputStreamTest < RUNIT::TestCase
include AssertEntry
def test_new
zis = ZipInputStream.new(TestZipFile::TEST_ZIP2.zipName)
assertStreamContents(zis, TestZipFile::TEST_ZIP2)
zis.close
end
def test_openWithBlock
ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName) {
|zis|
assertStreamContents(zis, TestZipFile::TEST_ZIP2)
}
end
def test_openWithoutBlock
zis = ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName)
assertStreamContents(zis, TestZipFile::TEST_ZIP2)
end
def test_incompleteReads
ZipInputStream.open(TestZipFile::TEST_ZIP2.zipName) {
|zis|
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[0], entry.name)
assert zis.gets.length > 0
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[1], entry.name)
assert_equals(0, entry.size)
assert_equals(nil, zis.gets)
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[2], entry.name)
assert zis.gets.length > 0
entry = zis.getNextEntry
assert_equals(TestZipFile::TEST_ZIP2.entryNames[3], entry.name)
assert zis.gets.length > 0
}
end
end
class TestFiles
RANDOM_ASCII_FILE1 = "randomAscii1.txt"
RANDOM_ASCII_FILE2 = "randomAscii2.txt"
RANDOM_ASCII_FILE3 = "randomAscii3.txt"
RANDOM_BINARY_FILE1 = "randomBinary1.bin"
RANDOM_BINARY_FILE2 = "randomBinary2.bin"
EMPTY_TEST_DIR = "emptytestdir"
ASCII_TEST_FILES = [ RANDOM_ASCII_FILE1, RANDOM_ASCII_FILE2, RANDOM_ASCII_FILE3 ]
BINARY_TEST_FILES = [ RANDOM_BINARY_FILE1, RANDOM_BINARY_FILE2 ]
TEST_DIRECTORIES = [ EMPTY_TEST_DIR ]
TEST_FILES = [ ASCII_TEST_FILES, BINARY_TEST_FILES, EMPTY_TEST_DIR ].flatten!
def TestFiles.createTestFiles(recreate)
if (recreate ||
! (TEST_FILES.inject(true) { |accum, element| accum && File.exists?(element) }))
ASCII_TEST_FILES.each_with_index {
|filename, index|
createRandomAscii(filename, 1E4 * (index+1))
}
BINARY_TEST_FILES.each_with_index {
|filename, index|
createRandomBinary(filename, 1E4 * (index+1))
}
ensureDir(EMPTY_TEST_DIR)
end
end
private
def TestFiles.createRandomAscii(filename, size)
File.open(filename, "wb") {
|file|
while (file.tell < size)
file << rand
end
}
end
def TestFiles.createRandomBinary(filename, size)
File.open(filename, "wb") {
|file|
while (file.tell < size)
file << rand.to_a.pack("V")
end
}
end
def TestFiles.ensureDir(name)
if File.exists?(name)
return if File.stat(name).directory?
File.delete(name)
end
Dir.mkdir(name)
end
end
# For representation and creation of
# test data
class TestZipFile
attr_accessor :zipName, :entryNames, :comment
def initialize(zipName, entryNames, comment = "")
@zipName=zipName
@entryNames=entryNames
@comment = comment
end
def TestZipFile.createTestZips(recreate)
files = Dir.entries(".")
if (recreate ||
! (files.index(TEST_ZIP1.zipName) &&
files.index(TEST_ZIP2.zipName) &&
files.index(TEST_ZIP3.zipName) &&
files.index(TEST_ZIP4.zipName) &&
files.index("empty.txt") &&
files.index("short.txt") &&
files.index("longAscii.txt") &&
files.index("longBinary.bin") ))
raise "failed to create test zip '#{TEST_ZIP1.zipName}'" unless
system("zip #{TEST_ZIP1.zipName} ziptest.rb")
raise "failed to remove entry from '#{TEST_ZIP1.zipName}'" unless
system("zip #{TEST_ZIP1.zipName} -d ziptest.rb")
File.open("empty.txt", "w") {}
File.open("short.txt", "w") { |file| file << "ABCDEF" }
ziptestTxt=""
File.open("ziptest.rb") { |file| ziptestTxt=file.read }
File.open("longAscii.txt", "w") {
|file|
while (file.tell < 1E5)
file << ziptestTxt
end
}
testBinaryPattern=""
File.open("empty.zip") { |file| testBinaryPattern=file.read }
testBinaryPattern *= 4
File.open("longBinary.bin", "wb") {
|file|
while (file.tell < 3E5)
file << testBinaryPattern << rand
end
}
raise "failed to create test zip '#{TEST_ZIP2.zipName}'" unless
system("zip #{TEST_ZIP2.zipName} #{TEST_ZIP2.entryNames.join(' ')}")
# without bash system interprets everything after echo as parameters to
# echo including | zip -z ...
raise "failed to add comment to test zip '#{TEST_ZIP2.zipName}'" unless
system("bash -c \"echo #{TEST_ZIP2.comment} | zip -z #{TEST_ZIP2.zipName}\"")
raise "failed to create test zip '#{TEST_ZIP3.zipName}'" unless
system("zip #{TEST_ZIP3.zipName} #{TEST_ZIP3.entryNames.join(' ')}")
raise "failed to create test zip '#{TEST_ZIP4.zipName}'" unless
system("zip #{TEST_ZIP4.zipName} #{TEST_ZIP4.entryNames.join(' ')}")
end
rescue
raise $!.to_s +
"\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" +
"to create test data. If you don't have it you can download\n" +
"the necessary test files at http://sf.net/projects/rubyzip."
end
TEST_ZIP1 = TestZipFile.new("empty.zip", [])
TEST_ZIP2 = TestZipFile.new("4entry.zip", %w{ longAscii.txt empty.txt short.txt longBinary.bin},
"my zip comment")
TEST_ZIP3 = TestZipFile.new("test1.zip", %w{ file1.txt })
TEST_ZIP4 = TestZipFile.new("zipWithDir.zip", [ "file1.txt",
TestFiles::EMPTY_TEST_DIR])
end
class AbstractOutputStreamTest < RUNIT::TestCase
class TestOutputStream
include AbstractOutputStream
attr_accessor :buffer
def initialize
@buffer = ""
end
def << (data)
@buffer << data
self
end
end
def setup
@outputStream = TestOutputStream.new
@origCommaSep = $,
@origOutputSep = $\
end
def teardown
$, = @origCommaSep
$\ = @origOutputSep
end
def test_write
count = @outputStream.write("a little string")
assert_equals("a little string", @outputStream.buffer)
assert_equals("a little string".length, count)
count = @outputStream.write(". a little more")
assert_equals("a little string. a little more", @outputStream.buffer)
assert_equals(". a little more".length, count)
end
def test_print
$\ = nil # record separator set to nil
@outputStream.print("hello")
assert_equals("hello", @outputStream.buffer)
@outputStream.print(" world.")
assert_equals("hello world.", @outputStream.buffer)
@outputStream.print(" You ok ", "out ", "there?")
assert_equals("hello world. You ok out there?", @outputStream.buffer)
$\ = "\n"
@outputStream.print
assert_equals("hello world. You ok out there?\n", @outputStream.buffer)
@outputStream.print("I sure hope so!")
assert_equals("hello world. You ok out there?\nI sure hope so!\n", @outputStream.buffer)
$, = "X"
@outputStream.buffer = ""
@outputStream.print("monkey", "duck", "zebra")
assert_equals("monkeyXduckXzebra\n", @outputStream.buffer)
$\ = nil
@outputStream.buffer = ""
@outputStream.print(20)
assert_equals("20", @outputStream.buffer)
end
def test_printf
@outputStream.printf("%d %04x", 123, 123)
assert_equals("123 007b", @outputStream.buffer)
end
def test_putc
@outputStream.putc("A")
assert_equals("A", @outputStream.buffer)
@outputStream.putc(65)
assert_equals("AA", @outputStream.buffer)
end
def test_puts
@outputStream.puts
assert_equals("\n", @outputStream.buffer)
@outputStream.puts("hello", "world")
assert_equals("\nhello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts("hello\n", "world\n")
assert_equals("hello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(["hello\n", "world\n"])
assert_equals("hello\nworld\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(["hello\n", "world\n"], "bingo")
assert_equals("hello\nworld\nbingo\n", @outputStream.buffer)
@outputStream.buffer = ""
@outputStream.puts(16, 20, 50, "hello")
assert_equals("16\n20\n50\nhello\n", @outputStream.buffer)
end
end
module CrcTest
def runCrcTest(compressorClass)
str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
fakeOut = AbstractOutputStreamTest::TestOutputStream.new
deflater = compressorClass.new(fakeOut)
deflater << str
assert_equals(0x919920fc, deflater.crc)
end
end
class PassThruCompressorTest < RUNIT::TestCase
include CrcTest
def test_size
File.open("dummy.txt", "wb") {
|file|
compressor = PassThruCompressor.new(file)
assert_equals(0, compressor.size)
t1 = "hello world"
t2 = ""
t3 = "bingo"
compressor << t1
assert_equals(compressor.size, t1.size)
compressor << t2
assert_equals(compressor.size, t1.size + t2.size)
compressor << t3
assert_equals(compressor.size, t1.size + t2.size + t3.size)
}
end
def test_crc
runCrcTest(PassThruCompressor)
end
end
class DeflaterTest < RUNIT::TestCase
include CrcTest
def test_outputOperator
txt = loadFile("ziptest.rb")
deflate(txt, "deflatertest.bin")
inflatedTxt = inflate("deflatertest.bin")
assert_equals(txt, inflatedTxt)
end
private
def loadFile(fileName)
txt = nil
File.open(fileName, "rb") { |f| txt = f.read }
end
def deflate(data, fileName)
File.open(fileName, "wb") {
|file|
deflater = Deflater.new(file)
deflater << data
deflater.finish
assert_equals(deflater.size, data.size)
file << "trailing data for zlib with -MAX_WBITS"
}
end
def inflate(fileName)
txt = nil
File.open(fileName, "rb") {
|file|
inflater = Inflater.new(file)
txt = inflater.read
}
end
def test_crc
runCrcTest(Deflater)
end
end
class ZipOutputStreamTest < RUNIT::TestCase
include AssertEntry
TEST_ZIP = TestZipFile::TEST_ZIP2.clone
TEST_ZIP.zipName = "output.zip"
def test_new
zos = ZipOutputStream.new(TEST_ZIP.zipName)
zos.comment = TEST_ZIP.comment
writeTestZip(zos)
zos.close
assertTestZipContents(TEST_ZIP)
end
def test_open
ZipOutputStream.open(TEST_ZIP.zipName) {
|zos|
zos.comment = TEST_ZIP.comment
writeTestZip(zos)
}
assertTestZipContents(TEST_ZIP)
end
def test_writingToClosedStream
assertIOErrorInClosedStream { |zos| zos << "hello world" }
assertIOErrorInClosedStream { |zos| zos.puts "hello world" }
assertIOErrorInClosedStream { |zos| zos.write "hello world" }
end
def test_cannotOpenFile
name = TestFiles::EMPTY_TEST_DIR
begin
zos = ZipOutputStream.open(name)
rescue Exception
assert($!.kind_of?(Errno::EISDIR) || # Linux
$!.kind_of?(Errno::EEXIST) || # Windows/cygwin
$!.kind_of?(Errno::EACCES), # Windows
"Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.type}")
end
end
def assertIOErrorInClosedStream
assert_exception(IOError) {
zos = ZipOutputStream.new("test_putOnClosedStream.zip")
zos.close
yield zos
}
end
def writeTestZip(zos)
TEST_ZIP.entryNames.each {
|entryName|
zos.putNextEntry(entryName)
File.open(entryName, "rb") { |f| zos.write(f.read) }
}
end
end
module Enumerable
def compareEnumerables(otherEnumerable)
otherAsArray = otherEnumerable.to_a
index=0
each_with_index {
|element, index|
return false unless yield(element, otherAsArray[index])
}
return index+1 == otherAsArray.size
end
end
class ZipCentralDirectoryEntryTest < RUNIT::TestCase
def test_readFromStream
File.open("testDirectory.bin", "rb") {
|file|
entry = ZipEntry.readCDirEntry(file)
assert_equals("longAscii.txt", entry.name)
assert_equals(ZipEntry::DEFLATED, entry.compressionMethod)
assert_equals(106490, entry.size)
assert_equals(3784, entry.compressedSize)
assert_equals(0xfcd1799c, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals("empty.txt", entry.name)
assert_equals(ZipEntry::STORED, entry.compressionMethod)
assert_equals(0, entry.size)
assert_equals(0, entry.compressedSize)
assert_equals(0x0, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals("short.txt", entry.name)
assert_equals(ZipEntry::STORED, entry.compressionMethod)
assert_equals(6, entry.size)
assert_equals(6, entry.compressedSize)
assert_equals(0xbb76fe69, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals("longBinary.bin", entry.name)
assert_equals(ZipEntry::DEFLATED, entry.compressionMethod)
assert_equals(1000024, entry.size)
assert_equals(70847, entry.compressedSize)
assert_equals(0x10da7d59, entry.crc)
assert_equals("", entry.comment)
entry = ZipEntry.readCDirEntry(file)
assert_equals(nil, entry)
# Fields that are not check by this test:
# version made by 2 bytes
# version needed to extract 2 bytes
# general purpose bit flag 2 bytes
# last mod file time 2 bytes
# last mod file date 2 bytes
# compressed size 4 bytes
# uncompressed size 4 bytes
# disk number start 2 bytes
# internal file attributes 2 bytes
# external file attributes 4 bytes
# relative offset of local header 4 bytes
# file name (variable size)
# extra field (variable size)
# file comment (variable size)
}
end
def test_ReadEntryFromTruncatedZipFile
fragment=""
File.open("testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
fragment.extend(IOizeString)
entry = ZipEntry.new
entry.readCDirEntry(fragment)
fail "ZipError expected"
rescue ZipError
end
end
class ZipCentralDirectoryTest < RUNIT::TestCase
def test_readFromStream
File.open(TestZipFile::TEST_ZIP2.zipName, "rb") {
|zipFile|
cdir = ZipCentralDirectory.readFromStream(zipFile)
assert_equals(TestZipFile::TEST_ZIP2.entryNames.size, cdir.size)
assert(cdir.compareEnumerables(TestZipFile::TEST_ZIP2.entryNames) {
|cdirEntry, testEntryName|
cdirEntry.name == testEntryName
})
assert_equals(TestZipFile::TEST_ZIP2.comment, cdir.comment)
}
end
def test_readFromInvalidStream
File.open("ziptest.rb", "rb") {
|zipFile|
cdir = ZipCentralDirectory.new
cdir.readFromStream(zipFile)
}
fail "ZipError expected!"
rescue ZipError
end
def test_ReadFromTruncatedZipFile
fragment=""
File.open("testDirectory.bin") { |f| fragment = f.read }
fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
fragment.extend(IOizeString)
entry = ZipCentralDirectory.new
entry.readFromStream(fragment)
fail "ZipError expected"
rescue ZipError
end
def test_writeToStream
entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
cdir = ZipCentralDirectory.new(entries, "my zip comment")
File.open("cdirtest.bin", "wb") { |f| cdir.writeToStream(f) }
cdirReadback = ZipCentralDirectory.new
File.open("cdirtest.bin", "rb") { |f| cdirReadback.readFromStream(f) }
assert_equals(cdir.entries, cdirReadback.entries)
end
def test_equality
cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"my zip comment")
cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"my zip comment")
cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "secondEntryName"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"comment?")
cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
"somethingExtra"),
ZipEntry.new("file.zip", "lastEntry.txt") ],
"comment?")
assert_equals(cdir1, cdir1)
assert_equals(cdir1, cdir2)
assert(cdir1 != cdir3)
assert(cdir2 != cdir3)
assert(cdir2 != cdir3)
assert(cdir3 != cdir4)
assert(cdir3 != "hello")
end
end
class BasicZipFileTest < RUNIT::TestCase
include AssertEntry
def setup
@zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zipName)
@testEntryNameIndex=0
end
def nextTestEntryName
retVal=TestZipFile::TEST_ZIP2.entryNames[@testEntryNameIndex]
@testEntryNameIndex+=1
return retVal
end
def test_entries
assert_equals(TestZipFile::TEST_ZIP2.entryNames, @zipFile.entries.map {|e| e.name} )
end
def test_each
@zipFile.each {
|entry|
assert_equals(nextTestEntryName, entry.name)
}
assert_equals(4, @testEntryNameIndex)
end
def test_foreach
ZipFile.foreach(TestZipFile::TEST_ZIP2.zipName) {
|entry|
assert_equals(nextTestEntryName, entry.name)
}
assert_equals(4, @testEntryNameIndex)
end
def test_getInputStream
@zipFile.each {
|entry|
assertEntry(nextTestEntryName, @zipFile.getInputStream(entry),
entry.name)
}
assert_equals(4, @testEntryNameIndex)
end
def test_getInputStreamBlock
fileAndEntryName = @zipFile.entries.first.name
@zipFile.getInputStream(fileAndEntryName) {
|zis|
assertEntryContentsForStream(fileAndEntryName,
zis,
fileAndEntryName)
}
end
end
class CommonZipFileFixture < RUNIT::TestCase
include AssertEntry
EMPTY_FILENAME = "emptyZipFile.zip"
TEST_ZIP = TestZipFile::TEST_ZIP2.clone
TEST_ZIP.zipName = "4entry_copy.zip"
def setup
File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
File.copy(TestZipFile::TEST_ZIP2.zipName, TEST_ZIP.zipName)
end
end
class ZipFileTest < CommonZipFileFixture
def test_createFromScratch
comment = "a short comment"
zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
zf.comment = comment
zf.close
zfRead = ZipFile.new(EMPTY_FILENAME)
assert_equals(comment, zfRead.comment)
assert_equals(0, zfRead.entries.length)
end
def test_add
srcFile = "ziptest.rb"
entryName = "newEntryName.rb"
assert(File.exists? srcFile)
zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
zf.add(entryName, srcFile)
zf.close
zfRead = ZipFile.new(EMPTY_FILENAME)
assert_equals("", zfRead.comment)
assert_equals(1, zfRead.entries.length)
assert_equals(entryName, zfRead.entries.first.name)
AssertEntry.assertContents(srcFile,
zfRead.getInputStream(entryName) { |zis| zis.read })
end
def test_addExistingEntryName
assert_exception(ZipEntryExistsError) {
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.add(zf.entries.first.name, "ziptest.rb")
}
}
end
def test_addExistingEntryNameReplace
gotCalled = false
replacedEntry = nil
ZipFile.open(TEST_ZIP.zipName) {
|zf|
replacedEntry = zf.entries.first.name
zf.add(replacedEntry, "ziptest.rb") { gotCalled = true; true }
}
assert(gotCalled)
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assertContains(zf, replacedEntry, "ziptest.rb")
}
end
def test_addDirectory
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
}
ZipFile.open(TEST_ZIP.zipName) {
|zf|
dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
assert(dirEntry.isDirectory)
}
end
def test_remove
entryToRemove, *remainingEntries = TEST_ZIP.entryNames
File.copy(TestZipFile::TEST_ZIP2.zipName, TEST_ZIP.zipName)
zf = ZipFile.new(TEST_ZIP.zipName)
assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
zf.remove(entryToRemove)
assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
assert_equals(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
zf.close
zfRead = ZipFile.new(TEST_ZIP.zipName)
assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
assert_equals(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
zfRead.close
end
def test_rename
entryToRename, *remainingEntries = TEST_ZIP.entryNames
zf = ZipFile.new(TEST_ZIP.zipName)
assert(zf.entries.map { |e| e.name }.include? entryToRename)
newName = "changed name"
assert(! zf.entries.map { |e| e.name }.include?(newName))
zf.rename(entryToRename, newName)
assert(zf.entries.map { |e| e.name }.include? newName)
zf.close
zfRead = ZipFile.new(TEST_ZIP.zipName)
assert(zfRead.entries.map { |e| e.name }.include? newName)
zfRead.close
end
def test_renameToExistingEntry
oldEntries = nil
ZipFile.open(TEST_ZIP.zipName) { |zf| oldEntries = zf.entries }
assert_exception(ZipEntryExistsError) {
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.rename(zf.entries[0], zf.entries[1].name)
}
}
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assert_equals(oldEntries.map{ |e| e.name }, zf.entries.map{ |e| e.name })
}
end
def test_renameToExistingEntryOverwrite
oldEntries = nil
ZipFile.open(TEST_ZIP.zipName) { |zf| oldEntries = zf.entries }
gotCalled = false
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
}
assert(gotCalled)
oldEntries.delete_at(0)
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assert_equals(oldEntries.map{ |e| e.name },
zf.entries.map{ |e| e.name })
}
end
def test_renameNonEntry
nonEntry = "bogusEntry"
targetEntry = "targetEntryName"
zf = ZipFile.new(TEST_ZIP.zipName)
assert(! zf.entries.include?(nonEntry))
assert_exception(ZipNoSuchEntryError) {
zf.rename(nonEntry, targetEntry)
}
zf.commit
assert(! zf.entries.include?(targetEntry))
ensure
zf.close
end
def test_renameEntryToExistingEntry
entry1, entry2, *remaining = TEST_ZIP.entryNames
zf = ZipFile.new(TEST_ZIP.zipName)
assert_exception(ZipEntryExistsError) {
zf.rename(entry1, entry2)
}
ensure
zf.close
end
def test_replace
unchangedEntries = TEST_ZIP.entryNames.dup
entryToReplace = unchangedEntries.delete_at(2)
newEntrySrcFilename = "ziptest.rb"
zf = ZipFile.new(TEST_ZIP.zipName)
zf.replace(entryToReplace, newEntrySrcFilename)
zf.close
zfRead = ZipFile.new(TEST_ZIP.zipName)
AssertEntry::assertContents(newEntrySrcFilename,
zfRead.getInputStream(entryToReplace) { |is| is.read })
zfRead.close
end
def test_replaceNonEntry
entryToReplace = "nonExistingEntryname"
ZipFile.open(TEST_ZIP.zipName) {
|zf|
assert_exception(ZipNoSuchEntryError) {
zf.replace(entryToReplace, "ziptest.rb")
}
}
end
def test_commit
newName = "renamedFirst"
zf = ZipFile.new(TEST_ZIP.zipName)
oldName = zf.entries.first
zf.rename(oldName, newName)
zf.commit
zfRead = ZipFile.new(TEST_ZIP.zipName)
assert(zfRead.entries.detect { |e| e.name == newName } != nil)
assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
zfRead.close
zf.close
end
# This test tests that after commit, you
# can delete the file you used to add the entry to the zip file
# with
def test_commitUseZipEntry
File.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
zf = ZipFile.open(TEST_ZIP.zipName)
zf.add("okToDelete.txt", "okToDelete.txt")
assertContains(zf, "okToDelete.txt")
zf.commit
File.move("okToDelete.txt", "okToDeleteMoved.txt")
assertContains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
end
# def test_close
# zf = ZipFile.new(TEST_ZIP.zipName)
# zf.close
# assert_exception(IOError) {
# zf.extract(TEST_ZIP.entryNames.first, "hullubullu")
# }
# end
def test_compound1
renamedName = "renamedName"
originalEntries = []
begin
zf = ZipFile.new(TEST_ZIP.zipName)
originalEntries = zf.entries.dup
assertNotContains(zf, TestFiles::RANDOM_ASCII_FILE1)
zf.add(TestFiles::RANDOM_ASCII_FILE1,
TestFiles::RANDOM_ASCII_FILE1)
assertContains(zf, TestFiles::RANDOM_ASCII_FILE1)
zf.rename(zf.entries[0], renamedName)
assertContains(zf, renamedName)
TestFiles::BINARY_TEST_FILES.each {
|filename|
zf.add(filename, filename)
assertContains(zf, filename)
}
assertContains(zf, originalEntries.last.to_s)
zf.remove(originalEntries.last.to_s)
assertNotContains(zf, originalEntries.last.to_s)
ensure
zf.close
end
begin
zfRead = ZipFile.new(TEST_ZIP.zipName)
assertContains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
assertContains(zfRead, renamedName)
TestFiles::BINARY_TEST_FILES.each {
|filename|
assertContains(zfRead, filename)
}
assertNotContains(zfRead, originalEntries.last.to_s)
ensure
zfRead.close
end
end
def test_compound2
begin
zf = ZipFile.new(TEST_ZIP.zipName)
originalEntries = zf.entries.dup
originalEntries.each {
|entry|
zf.remove(entry)
assertNotContains(zf, entry)
}
assert(zf.entries.empty?)
TestFiles::ASCII_TEST_FILES.each {
|filename|
zf.add(filename, filename)
assertContains(zf, filename)
}
assert_equals(zf.entries.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
assertNotContains(zf, TestFiles::ASCII_TEST_FILES[0])
assertContains(zf, "newName")
ensure
zf.close
end
begin
zfRead = ZipFile.new(TEST_ZIP.zipName)
asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
asciiTestFiles.shift
asciiTestFiles.each {
|filename|
assertContains(zf, filename)
}
assertContains(zf, "newName")
ensure
zfRead.close
end
end
private
def assertContains(zf, entryName, filename = entryName)
assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
assertEntryContents(zf, entryName, filename) if File.exists?(filename)
end
def assertNotContains(zf, entryName)
assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
end
end
class ZipFileExtractTest < CommonZipFileFixture
EXTRACTED_FILENAME = "extEntry"
ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entryNames.reverse
def setup
super
File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
end
def test_extract
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
assert(File.exists? EXTRACTED_FILENAME)
AssertEntry::assertContents(EXTRACTED_FILENAME,
zf.getInputStream(ENTRY_TO_EXTRACT) { |is| is.read })
}
end
def test_extractExists
writtenText = "written text"
File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
assert_exception(ZipDestinationFileExistsError) {
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.extract(zf.entries.first, EXTRACTED_FILENAME)
}
}
File.open(EXTRACTED_FILENAME, "r") {
|f|
assert_equals(writtenText, f.read)
}
end
def test_extractExistsOverwrite
writtenText = "written text"
File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
gotCalled = false
ZipFile.open(TEST_ZIP.zipName) {
|zf|
zf.extract(zf.entries.first, EXTRACTED_FILENAME) { gotCalled = true; true }
}
assert(gotCalled)
File.open(EXTRACTED_FILENAME, "r") {
|f|
assert(writtenText != f.read)
}
end
def test_extractNonEntry
zf = ZipFile.new(TEST_ZIP.zipName)
assert_exception(ZipNoSuchEntryError) { zf.extract("nonExistingEntry", "nonExistingEntry") }
ensure
zf.close if zf
end
def test_extractNonEntry2
outFile = "outfile"
assert_exception(ZipNoSuchEntryError) {
zf = ZipFile.new(TEST_ZIP.zipName)
nonEntry = "hotdog-diddelidoo"
assert(! zf.entries.include?(nonEntry))
zf.extract(nonEntry, outFile)
zf.close
}
assert(! File.exists?(outFile))
end
end
class ZipFileExtractDirectoryTest < CommonZipFileFixture
TEST_OUT_NAME = "emptyOutDir"
def openZip(&aProc)
assert(aProc != nil)
ZipFile.open(TestZipFile::TEST_ZIP4.zipName, &aProc)
end
def extractTestDir(&aProc)
openZip {
|zf|
zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
}
end
def setup
super
Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
end
def test_extractDirectory
extractTestDir
assert(File.directory? TEST_OUT_NAME)
end
def test_extractDirectoryExistsAsDir
Dir.mkdir TEST_OUT_NAME
extractTestDir
assert(File.directory? TEST_OUT_NAME)
end
def test_extractDirectoryExistsAsFile
File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
assert_exception(ZipDestinationFileExistsError) { extractTestDir }
end
def test_extractDirectoryExistsAsFileOverwrite
File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
gotCalled = false
extractTestDir {
|entry, destPath|
gotCalled = true
assert_equals(TEST_OUT_NAME, destPath)
assert(entry.isDirectory)
true
}
assert(gotCalled)
assert(File.directory? TEST_OUT_NAME)
end
end
TestFiles::createTestFiles(ARGV.index("recreate") != nil ||
ARGV.index("recreateonly") != nil)
TestZipFile::createTestZips(ARGV.index("recreate") != nil ||
ARGV.index("recreateonly") != nil)
exit if ARGV.index("recreateonly") != nil
#require 'runit/cui/testrunner'
#RUNIT::CUI::TestRunner.run(ZipFileTest.suite)
# Copyright (C) 2002 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.