352 lines
10 KiB
Ruby
352 lines
10 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'test_helper'
|
|
|
|
class ZipEntryTest < MiniTest::Test
|
|
include ZipEntryData
|
|
|
|
def teardown
|
|
::Zip.reset!
|
|
end
|
|
|
|
def test_constructor_and_getters
|
|
entry = ::Zip::Entry.new(
|
|
TEST_ZIPFILE, TEST_NAME,
|
|
comment: TEST_COMMENT, extra: TEST_EXTRA,
|
|
compressed_size: TEST_COMPRESSED_SIZE,
|
|
crc: TEST_CRC, size: TEST_SIZE, time: TEST_TIME,
|
|
compression_method: TEST_COMPRESSIONMETHOD,
|
|
compression_level: TEST_COMPRESSIONLEVEL
|
|
)
|
|
|
|
assert_equal(TEST_COMMENT, entry.comment)
|
|
assert_equal(TEST_COMPRESSED_SIZE, entry.compressed_size)
|
|
assert_equal(TEST_CRC, entry.crc)
|
|
assert_instance_of(::Zip::ExtraField, entry.extra)
|
|
assert_equal(TEST_COMPRESSIONMETHOD, entry.compression_method)
|
|
assert_equal(TEST_NAME, entry.name)
|
|
assert_equal(TEST_SIZE, entry.size)
|
|
|
|
# Reverse times when testing because we need to use DOSTime#== for the
|
|
# comparison, not Time#==.
|
|
assert_equal(entry.time, TEST_TIME)
|
|
end
|
|
|
|
def test_is_directory_and_is_file
|
|
assert(::Zip::Entry.new(TEST_ZIPFILE, 'hello').file?)
|
|
assert(!::Zip::Entry.new(TEST_ZIPFILE, 'hello').directory?)
|
|
|
|
assert(::Zip::Entry.new(TEST_ZIPFILE, 'dir/hello').file?)
|
|
assert(!::Zip::Entry.new(TEST_ZIPFILE, 'dir/hello').directory?)
|
|
|
|
assert(::Zip::Entry.new(TEST_ZIPFILE, 'hello/').directory?)
|
|
assert(!::Zip::Entry.new(TEST_ZIPFILE, 'hello/').file?)
|
|
|
|
assert(::Zip::Entry.new(TEST_ZIPFILE, 'dir/hello/').directory?)
|
|
assert(!::Zip::Entry.new(TEST_ZIPFILE, 'dir/hello/').file?)
|
|
end
|
|
|
|
def test_equality
|
|
entry1 = ::Zip::Entry.new(
|
|
'file.zip', 'name',
|
|
comment: 'isNotCompared', extra: 'something extra',
|
|
compressed_size: 123, crc: 1234, size: 10_000
|
|
)
|
|
|
|
entry2 = ::Zip::Entry.new(
|
|
'file.zip', 'name',
|
|
comment: 'isNotComparedXXX', extra: 'something extra',
|
|
compressed_size: 123, crc: 1234, size: 10_000
|
|
)
|
|
|
|
entry3 = ::Zip::Entry.new(
|
|
'file.zip', 'name2',
|
|
comment: 'isNotComparedXXX', extra: 'something extra',
|
|
compressed_size: 123, crc: 1234, size: 10_000
|
|
)
|
|
|
|
entry4 = ::Zip::Entry.new(
|
|
'file.zip', 'name2',
|
|
comment: 'isNotComparedXXX', extra: 'something extraXX',
|
|
compressed_size: 123, crc: 1234, size: 10_000
|
|
)
|
|
|
|
entry5 = ::Zip::Entry.new(
|
|
'file.zip', 'name2',
|
|
comment: 'isNotComparedXXX', extra: 'something extraXX',
|
|
compressed_size: 12, crc: 1234, size: 10_000
|
|
)
|
|
|
|
entry6 = ::Zip::Entry.new(
|
|
'file.zip', 'name2',
|
|
comment: 'isNotComparedXXX', extra: 'something extraXX',
|
|
compressed_size: 12, crc: 123, size: 10_000
|
|
)
|
|
|
|
entry7 = ::Zip::Entry.new(
|
|
'file.zip', 'name2', comment: 'isNotComparedXXX',
|
|
extra: 'something extraXX', compressed_size: 12, crc: 123, size: 10_000,
|
|
compression_method: ::Zip::Entry::STORED
|
|
)
|
|
|
|
entry8 = ::Zip::Entry.new(
|
|
'file.zip', 'name2',
|
|
comment: 'isNotComparedXXX', extra: 'something extraXX',
|
|
compressed_size: 12, crc: 123, size: 100_000,
|
|
compression_method: ::Zip::Entry::STORED
|
|
)
|
|
|
|
assert_equal(entry1, entry1)
|
|
assert_equal(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
|
|
|
|
def test_compare
|
|
assert_equal(0, (::Zip::Entry.new('zf.zip', 'a') <=> ::Zip::Entry.new('zf.zip', 'a')))
|
|
assert_equal(1, (::Zip::Entry.new('zf.zip', 'b') <=> ::Zip::Entry.new('zf.zip', 'a')))
|
|
assert_equal(-1, (::Zip::Entry.new('zf.zip', 'a') <=> ::Zip::Entry.new('zf.zip', 'b')))
|
|
|
|
entries = [
|
|
::Zip::Entry.new('zf.zip', '5'),
|
|
::Zip::Entry.new('zf.zip', '1'),
|
|
::Zip::Entry.new('zf.zip', '3'),
|
|
::Zip::Entry.new('zf.zip', '4'),
|
|
::Zip::Entry.new('zf.zip', '0'),
|
|
::Zip::Entry.new('zf.zip', '2')
|
|
]
|
|
|
|
entries.sort!
|
|
assert_equal('0', entries[0].to_s)
|
|
assert_equal('1', entries[1].to_s)
|
|
assert_equal('2', entries[2].to_s)
|
|
assert_equal('3', entries[3].to_s)
|
|
assert_equal('4', entries[4].to_s)
|
|
assert_equal('5', entries[5].to_s)
|
|
end
|
|
|
|
def test_parent_as_string
|
|
entry1 = ::Zip::Entry.new('zf.zip', 'aa')
|
|
entry2 = ::Zip::Entry.new('zf.zip', 'aa/')
|
|
entry3 = ::Zip::Entry.new('zf.zip', 'aa/bb')
|
|
entry4 = ::Zip::Entry.new('zf.zip', 'aa/bb/')
|
|
entry5 = ::Zip::Entry.new('zf.zip', 'aa/bb/cc')
|
|
entry6 = ::Zip::Entry.new('zf.zip', 'aa/bb/cc/')
|
|
|
|
assert_nil(entry1.parent_as_string)
|
|
assert_nil(entry2.parent_as_string)
|
|
assert_equal('aa/', entry3.parent_as_string)
|
|
assert_equal('aa/', entry4.parent_as_string)
|
|
assert_equal('aa/bb/', entry5.parent_as_string)
|
|
assert_equal('aa/bb/', entry6.parent_as_string)
|
|
end
|
|
|
|
def test_entry_name_cannot_start_with_slash
|
|
error = assert_raises(::Zip::EntryNameError) do
|
|
::Zip::Entry.new('zf.zip', '/hej/der')
|
|
end
|
|
assert_match(/'\/hej\/der'/, error.message)
|
|
end
|
|
|
|
def test_entry_name_cannot_be_too_long
|
|
name = 'a' * 65_535
|
|
::Zip::Entry.new('', name) # Should not raise anything.
|
|
|
|
error = assert_raises(::Zip::EntryNameError) do
|
|
::Zip::Entry.new('', "a#{name}")
|
|
end
|
|
assert_match(/65,536/, error.message)
|
|
end
|
|
|
|
def test_store_file_without_compression
|
|
Dir.mktmpdir do |tmp|
|
|
tmp_zip = File.join(tmp, 'no_compress.zip')
|
|
|
|
Zip.setup do |z|
|
|
z.write_zip64_support = false
|
|
end
|
|
|
|
zipfile = Zip::File.open(tmp_zip, create: true)
|
|
|
|
mimetype_entry = Zip::Entry.new(
|
|
zipfile, # @zipfile
|
|
'mimetype', # @name
|
|
compression_method: Zip::Entry::STORED
|
|
)
|
|
zipfile.add(mimetype_entry, 'test/data/mimetype')
|
|
|
|
files = Dir[File.join('test/data/globTest', '**', '**')]
|
|
files.each do |file|
|
|
zipfile.add(file.sub('test/data/globTest/', ''), file)
|
|
end
|
|
|
|
zipfile.close
|
|
|
|
f = File.open(tmp_zip, 'rb')
|
|
first_100_bytes = f.read(100)
|
|
f.close
|
|
|
|
assert_match(/mimetypeapplication\/epub\+zip/, first_100_bytes)
|
|
end
|
|
end
|
|
|
|
def test_encrypted?
|
|
entry = Zip::Entry.new
|
|
entry.gp_flags = 1
|
|
assert_equal(true, entry.encrypted?)
|
|
|
|
entry.gp_flags = 0
|
|
assert_equal(false, entry.encrypted?)
|
|
end
|
|
|
|
def test_incomplete?
|
|
entry = Zip::Entry.new
|
|
entry.gp_flags = 8
|
|
assert_equal(true, entry.incomplete?)
|
|
|
|
entry.gp_flags = 0
|
|
assert_equal(false, entry.incomplete?)
|
|
end
|
|
|
|
def test_compression_level_flags
|
|
[
|
|
[Zip.default_compression, 0],
|
|
[0, 0],
|
|
[1, 6],
|
|
[2, 4],
|
|
[3, 0],
|
|
[7, 0],
|
|
[8, 2],
|
|
[9, 2]
|
|
].each do |level, flags|
|
|
# Check flags are set correctly when DEFLATED is (implicitly) specified.
|
|
e_def = Zip::Entry.new(
|
|
'', '',
|
|
compression_level: level
|
|
)
|
|
assert_equal(flags, e_def.gp_flags & 0b110)
|
|
|
|
# Check that flags are not set when STORED is specified.
|
|
e_sto = Zip::Entry.new(
|
|
'', '',
|
|
compression_method: Zip::Entry::STORED,
|
|
compression_level: level
|
|
)
|
|
assert_equal(0, e_sto.gp_flags & 0b110)
|
|
end
|
|
|
|
# Check that a directory entry's flags are not set, even if DEFLATED
|
|
# is specified.
|
|
e_dir = Zip::Entry.new(
|
|
'', 'd/', compression_method: Zip::Entry::DEFLATED, compression_level: 1
|
|
)
|
|
assert_equal(0, e_dir.gp_flags & 0b110)
|
|
end
|
|
|
|
def test_compression_method_reader
|
|
[
|
|
[Zip.default_compression, Zip::Entry::DEFLATED],
|
|
[0, Zip::Entry::STORED],
|
|
[1, Zip::Entry::DEFLATED],
|
|
[9, Zip::Entry::DEFLATED]
|
|
].each do |level, method|
|
|
# Check that the correct method is returned when DEFLATED is specified.
|
|
entry = Zip::Entry.new(compression_level: level)
|
|
assert_equal(method, entry.compression_method)
|
|
end
|
|
|
|
# Check that the correct method is returned when STORED is specified.
|
|
entry = Zip::Entry.new(
|
|
compression_method: Zip::Entry::STORED, compression_level: 1
|
|
)
|
|
assert_equal(Zip::Entry::STORED, entry.compression_method)
|
|
|
|
# Check that directories are always STORED, whatever level is specified.
|
|
entry = Zip::Entry.new(
|
|
'', 'd/', compression_method: Zip::Entry::DEFLATED, compression_level: 1
|
|
)
|
|
assert_equal(Zip::Entry::STORED, entry.compression_method)
|
|
end
|
|
|
|
def test_set_time_as_dos_time
|
|
entry = ::Zip::Entry.new
|
|
assert(entry.time.kind_of?(::Zip::DOSTime))
|
|
entry.time = Time.now
|
|
assert(entry.time.kind_of?(::Zip::DOSTime))
|
|
entry.time = ::Zip::DOSTime.now
|
|
assert(entry.time.kind_of?(::Zip::DOSTime))
|
|
end
|
|
|
|
def test_atime
|
|
entry = ::Zip::Entry.new
|
|
time = Time.new(1999, 12, 31, 23, 59, 59)
|
|
|
|
entry.atime = time
|
|
assert(entry.dirty?)
|
|
assert_equal(::Zip::DOSTime.from_time(time), entry.atime)
|
|
refute_equal(entry.time, entry.atime)
|
|
assert(entry.atime.kind_of?(::Zip::DOSTime))
|
|
assert_nil(entry.ctime)
|
|
end
|
|
|
|
def test_ctime
|
|
entry = ::Zip::Entry.new
|
|
time = Time.new(1999, 12, 31, 23, 59, 59)
|
|
|
|
entry.ctime = time
|
|
assert(entry.dirty?)
|
|
assert_equal(::Zip::DOSTime.from_time(time), entry.ctime)
|
|
refute_equal(entry.time, entry.ctime)
|
|
assert(entry.ctime.kind_of?(::Zip::DOSTime))
|
|
assert_nil(entry.atime)
|
|
end
|
|
|
|
def test_mtime
|
|
entry = ::Zip::Entry.new
|
|
time = Time.new(1999, 12, 31, 23, 59, 59)
|
|
|
|
entry.mtime = time
|
|
assert(entry.dirty?)
|
|
assert_equal(::Zip::DOSTime.from_time(time), entry.mtime)
|
|
assert_equal(entry.time, entry.mtime)
|
|
assert(entry.mtime.kind_of?(::Zip::DOSTime))
|
|
assert_nil(entry.atime)
|
|
assert_nil(entry.ctime)
|
|
end
|
|
|
|
def test_time
|
|
entry = ::Zip::Entry.new
|
|
time = Time.new(1999, 12, 31, 23, 59, 59)
|
|
|
|
entry.time = time
|
|
assert(entry.dirty?)
|
|
assert_equal(::Zip::DOSTime.from_time(time), entry.time)
|
|
assert_equal(entry.mtime, entry.time)
|
|
assert(entry.time.kind_of?(::Zip::DOSTime))
|
|
assert_nil(entry.atime)
|
|
assert_nil(entry.ctime)
|
|
end
|
|
|
|
def test_ensure_entry_time_set_to_file_mtime
|
|
entry = ::Zip::Entry.new
|
|
entry.gather_fileinfo_from_srcpath('test/data/mimetype')
|
|
assert_equal(entry.time, File.stat('test/data/mimetype').mtime)
|
|
end
|
|
|
|
def test_absolute_time
|
|
entry = ::Zip::Entry.new
|
|
refute(entry.absolute_time?)
|
|
|
|
entry.time = Time.now
|
|
assert(entry.absolute_time?)
|
|
end
|
|
end
|