ZipCentralDirectoryEntryTest now runs
This commit is contained in:
parent
d4bf9328ef
commit
badae1edeb
Binary file not shown.
106
zip.rb
106
zip.rb
|
@ -205,7 +205,7 @@ class ZipEntry
|
||||||
end
|
end
|
||||||
|
|
||||||
def isDirectory
|
def isDirectory
|
||||||
return (/\/$/ =~ @name) != nil
|
return (%r{\/$} =~ @name) != nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def localEntryOffset
|
def localEntryOffset
|
||||||
|
@ -240,7 +240,7 @@ class ZipLocalEntry < ZipEntry
|
||||||
def readFromStream(io)
|
def readFromStream(io)
|
||||||
unless (ZipEntry::readZipLong(io) == LOCAL_ENTRY_SIGNATURE)
|
unless (ZipEntry::readZipLong(io) == LOCAL_ENTRY_SIGNATURE)
|
||||||
raise ZipError,
|
raise ZipError,
|
||||||
"Zip Local Header magic '#{LOCAL_ENTRY_SIGNATURE} not found"
|
"Zip local header magic '#{LOCAL_ENTRY_SIGNATURE} not found"
|
||||||
end
|
end
|
||||||
@localHeaderOffset = io. tell - 4
|
@localHeaderOffset = io. tell - 4
|
||||||
@version = ZipEntry::readZipShort(io)
|
@version = ZipEntry::readZipShort(io)
|
||||||
|
@ -266,20 +266,94 @@ class ZipLocalEntry < ZipEntry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# class ZipCentralDirectoryEntry < ZipEntry
|
class ZipCentralDirectoryEntry < ZipEntry
|
||||||
# ZIP_CENTRAL_DIRECTORY_ENTRY_SIGNATURE = 0x02014b50
|
CENTRAL_DIRECTORY_ENTRY_SIGNATURE = 0x02014b50
|
||||||
|
|
||||||
# def readFromStream(io)
|
def readFromStream(io)
|
||||||
# end
|
unless (ZipEntry::readZipLong(io) == CENTRAL_DIRECTORY_ENTRY_SIGNATURE)
|
||||||
|
raise ZipError,
|
||||||
# def ZipCentralDirectoryEntry.readFromStream(io)
|
"Zip central directory header magic '#{CENTRAL_DIRECTORY_ENTRY_SIGNATURE} not found"
|
||||||
# entry = new()
|
end
|
||||||
# entry.readFromStream(io)
|
@version = ZipEntry::readZipShort(io)
|
||||||
# return entry
|
@versionNeededToExtract = ZipEntry::readZipShort(io)
|
||||||
# rescue ZipError
|
@gpFlags = ZipEntry::readZipShort(io)
|
||||||
# return nil
|
@compressionMethod = ZipEntry::readZipShort(io)
|
||||||
# end
|
@lastModTime = ZipEntry::readZipShort(io)
|
||||||
# end
|
@lastModDate = ZipEntry::readZipShort(io)
|
||||||
|
@crc = ZipEntry::readZipLong(io)
|
||||||
|
@compressedSize = ZipEntry::readZipLong(io)
|
||||||
|
@size = ZipEntry::readZipLong(io)
|
||||||
|
nameLength = ZipEntry::readZipShort(io)
|
||||||
|
extraLength = ZipEntry::readZipShort(io)
|
||||||
|
commentLength = ZipEntry::readZipShort(io)
|
||||||
|
diskNumberStart = ZipEntry::readZipShort(io)
|
||||||
|
@internalFileAttributes = ZipEntry::readZipShort(io)
|
||||||
|
@externalFileAttributes = ZipEntry::readZipLong(io)
|
||||||
|
@localHeaderOffset = ZipEntry::readZipLong(io)
|
||||||
|
@name = io.read(nameLength)
|
||||||
|
@extra = io.read(extraLength)
|
||||||
|
@comment = io.read(commentLength)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ZipCentralDirectoryEntry.readFromStream(io)
|
||||||
|
entry = new()
|
||||||
|
entry.readFromStream(io)
|
||||||
|
return entry
|
||||||
|
rescue ZipError
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# File header:
|
||||||
|
|
||||||
|
# central file header signature 4 bytes (0x02014b50)
|
||||||
|
# version made by 2 bytes
|
||||||
|
# version needed to extract 2 bytes
|
||||||
|
# general purpose bit flag 2 bytes
|
||||||
|
# compression method 2 bytes
|
||||||
|
# last mod file time 2 bytes
|
||||||
|
# last mod file date 2 bytes
|
||||||
|
# crc-32 4 bytes
|
||||||
|
# compressed size 4 bytes
|
||||||
|
# uncompressed size 4 bytes
|
||||||
|
# file name length 2 bytes
|
||||||
|
# extra field length 2 bytes
|
||||||
|
# file comment length 2 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 of central dir signature 4 bytes (0x06054b50)
|
||||||
|
# number of this disk 2 bytes
|
||||||
|
# number of the disk with the
|
||||||
|
# start of the central directory 2 bytes
|
||||||
|
# total number of entries in the
|
||||||
|
# central directory on this disk 2 bytes
|
||||||
|
# total number of entries in
|
||||||
|
# the central directory 2 bytes
|
||||||
|
# size of the central directory 4 bytes
|
||||||
|
# offset of start of central
|
||||||
|
# directory with respect to
|
||||||
|
# the starting disk number 4 bytes
|
||||||
|
# .ZIP file comment length 2 bytes
|
||||||
|
# .ZIP file comment (variable size)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Digital signature:
|
||||||
|
|
||||||
|
# header signature 4 bytes (0x05054b50)
|
||||||
|
# size of data 2 bytes
|
||||||
|
# signature data (variable size)
|
||||||
|
|
||||||
|
|
||||||
class ZipError < RuntimeError
|
class ZipError < RuntimeError
|
||||||
end
|
end
|
||||||
|
|
113
ziptest.rb
113
ziptest.rb
|
@ -211,11 +211,12 @@ end
|
||||||
# For representation and creation of
|
# For representation and creation of
|
||||||
# test data
|
# test data
|
||||||
class TestZipFile
|
class TestZipFile
|
||||||
attr_reader :zipName, :entryNames
|
attr_reader :zipName, :entryNames, :comment
|
||||||
|
|
||||||
def initialize(zipName, entryNames)
|
def initialize(zipName, entryNames, comment = "")
|
||||||
@zipName=zipName
|
@zipName=zipName
|
||||||
@entryNames=entryNames
|
@entryNames=entryNames
|
||||||
|
@comment = comment
|
||||||
@@testZips << self
|
@@testZips << self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -264,6 +265,8 @@ class TestZipFile
|
||||||
}
|
}
|
||||||
raise "failed to create test zip '#{TEST_ZIP2.zipName}'" unless
|
raise "failed to create test zip '#{TEST_ZIP2.zipName}'" unless
|
||||||
system("zip #{TEST_ZIP2.zipName} #{TEST_ZIP2.entryNames.join(' ')}")
|
system("zip #{TEST_ZIP2.zipName} #{TEST_ZIP2.entryNames.join(' ')}")
|
||||||
|
raise "failed to add comment to test zip '#{TEST_ZIP2.zipName}'" unless
|
||||||
|
system("echo '#{TEST_ZIP2.comment}' | zip #{TEST_ZIP2.zipName}")
|
||||||
|
|
||||||
raise "failed to create test zip '#{TEST_ZIP3.zipName}'" unless
|
raise "failed to create test zip '#{TEST_ZIP3.zipName}'" unless
|
||||||
system("zip #{TEST_ZIP3.zipName} #{TEST_ZIP3.entryNames.join(' ')}")
|
system("zip #{TEST_ZIP3.zipName} #{TEST_ZIP3.entryNames.join(' ')}")
|
||||||
|
@ -271,36 +274,98 @@ class TestZipFile
|
||||||
end
|
end
|
||||||
|
|
||||||
TEST_ZIP1 = TestZipFile.new("empty.zip", [])
|
TEST_ZIP1 = TestZipFile.new("empty.zip", [])
|
||||||
TEST_ZIP2 = TestZipFile.new("4entry.zip", %w{ longAscii.txt empty.txt short.txt longBinary.bin})
|
TEST_ZIP2 = TestZipFile.new("4entry.zip", %w{ longAscii.txt empty.txt short.txt longBinary.bin},
|
||||||
|
"a nice comment")
|
||||||
TEST_ZIP3 = TestZipFile.new("test1.zip", %w{ file1.txt })
|
TEST_ZIP3 = TestZipFile.new("test1.zip", %w{ file1.txt })
|
||||||
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 = ZipCentralDirectoryEntry.readFromStream(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 = ZipCentralDirectoryEntry.readFromStream(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 = ZipCentralDirectoryEntry.readFromStream(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 = ZipCentralDirectoryEntry.readFromStream(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 = ZipCentralDirectoryEntry.readFromStream(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
|
||||||
|
end
|
||||||
|
|
||||||
class ZipCentralDirectoryTest < RUNIT::TestCase
|
class ZipCentralDirectoryTest < RUNIT::TestCase
|
||||||
|
|
||||||
def test_readFromStream
|
def test_readFromStream
|
||||||
File.open(TestZipFile::TEST_ZIP2.zipName, "rb") {
|
File.open(TestZipFile::TEST_ZIP2.zipName, "rb") {
|
||||||
|zipFile|
|
|zipFile|
|
||||||
cdir = ZipCentralDirectory.new(zipFile)
|
cdir = ZipCentralDirectory.new(zipFile)
|
||||||
######################################################################
|
|
||||||
# IN PROGRESS: write this test, then ZipCentralDirectory,
|
|
||||||
# then ZipCentralDirectoryEntryTest, then ZipCentralDirectory,
|
|
||||||
# then check ZipFileTest, then write ZipFile
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
# end of central dir signature 4 bytes (0x06054b50)
|
assert_equals(TestZipFile::TEST_ZIP2.entryNames.size, cdir)
|
||||||
# number of this disk 2 bytes
|
assert_equals(cdir.compareEnumerables(TestZipFile::TEST_ZIP2.entryNames) {
|
||||||
# number of the disk with the
|
|cdirEntry, testEntryName|
|
||||||
# start of the central directory 2 bytes
|
cdirEntry.name == testEntryName
|
||||||
# total number of entries in the
|
})
|
||||||
# central directory on this disk 2 bytes
|
assert_equals(TestZipFile::TEST_ZIP2.comment, cdir.comment)
|
||||||
# total number of entries in
|
|
||||||
# the central directory 2 bytes
|
|
||||||
# size of the central directory 4 bytes
|
|
||||||
# offset of start of central
|
|
||||||
# directory with respect to
|
|
||||||
# the starting disk number 4 bytes
|
|
||||||
# .ZIP file comment length 2 bytes
|
|
||||||
# .ZIP file comment (variable size)
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -314,8 +379,8 @@ class ZipCentralDirectoryTest < RUNIT::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Tests yet to write
|
|
||||||
# ZipFile
|
|
||||||
class ZipFileTest < RUNIT::TestCase
|
class ZipFileTest < RUNIT::TestCase
|
||||||
include AssertEntry
|
include AssertEntry
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue