Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/models/zip_file/reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def read(file_path)
raise ArgumentError, "Cannot read directory entry: #{file_path}" if entry.filename.end_with?("/")

if block_given?
yield ZipFile::Reader::ExtractorIO.new(entry, @io)
yield ZipFile::Reader::IO.new(entry, @io)
else
entry.extractor_from(@io).extract
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class ZipFile::Reader::ExtractorIO
class ZipFile::Reader::IO
def initialize(entry, io)
@entry = entry
@io = io
Expand Down
17 changes: 1 addition & 16 deletions app/models/zip_file/writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def initialize(io = nil)
end

def io
@counting_io ||= CountingIO.new(self)
@io ||= ZipFile::Writer::IO.new(self)
end

def stream_to(io)
Expand Down Expand Up @@ -55,19 +55,4 @@ def checksum
def streamer
@streamer ||= ZipKit::Streamer.new(@output_io)
end

class CountingIO
def initialize(writer)
@writer = writer
end

def write(data)
@writer.write(data)
end

def <<(data)
write(data)
self
end
end
end
18 changes: 18 additions & 0 deletions app/models/zip_file/writer/io.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class ZipFile::Writer::IO
def initialize(writer)
@writer = writer
end

def write(data)
@writer.write(data)
end

def <<(data)
write(data)
self
end

def size
@writer.byte_size
end
end
141 changes: 141 additions & 0 deletions test/models/zip_file_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
require "test_helper"

class ZipFileTest < ActiveSupport::TestCase
test "writer io exposes size for S3 multipart upload detection" do
writer = ZipFile::Writer.new

assert_respond_to writer.io, :size
assert_equal writer.byte_size, writer.io.size
end

test "writer adds files with content" do
tempfile = Tempfile.new([ "test", ".zip" ])
tempfile.binmode

writer = ZipFile::Writer.new(tempfile)
writer.add_file("hello.txt", "Hello, World!")
writer.close

assert writer.exists?("hello.txt")
assert_not writer.exists?("missing.txt")
end

test "writer adds files with block" do
tempfile = Tempfile.new([ "test", ".zip" ])
tempfile.binmode

writer = ZipFile::Writer.new(tempfile)
writer.add_file("hello.txt") { |sink| sink.write("Hello, World!") }
writer.close

assert writer.exists?("hello.txt")
end

test "writer globs entries" do
tempfile = Tempfile.new([ "test", ".zip" ])
tempfile.binmode

writer = ZipFile::Writer.new(tempfile)
writer.add_file("docs/readme.txt", "Readme")
writer.add_file("docs/guide.txt", "Guide")
writer.add_file("images/logo.png", "PNG data")
writer.close

assert_equal [ "docs/guide.txt", "docs/readme.txt" ], writer.glob("docs/*.txt")
assert_equal [ "images/logo.png" ], writer.glob("**/*.png")
end

test "reader reads file content" do
tempfile = create_test_zip("hello.txt" => "Hello, World!")

reader = ZipFile::Reader.new(tempfile)
content = reader.read("hello.txt")

assert_equal "Hello, World!", content
end

test "reader reads file with block" do
tempfile = create_test_zip("hello.txt" => "Hello, World!")

reader = ZipFile::Reader.new(tempfile)
content = nil
reader.read("hello.txt") { |io| content = io.read }

assert_equal "Hello, World!", content
end

test "reader raises for missing file" do
tempfile = create_test_zip("hello.txt" => "Hello")

reader = ZipFile::Reader.new(tempfile)

assert_raises(ArgumentError) { reader.read("missing.txt") }
end

test "reader checks file existence" do
tempfile = create_test_zip("hello.txt" => "Hello")

reader = ZipFile::Reader.new(tempfile)

assert reader.exists?("hello.txt")
assert_not reader.exists?("missing.txt")
end

test "reader globs entries" do
tempfile = create_test_zip(
"docs/readme.txt" => "Readme",
"docs/guide.txt" => "Guide",
"images/logo.png" => "PNG"
)

reader = ZipFile::Reader.new(tempfile)

assert_equal [ "docs/guide.txt", "docs/readme.txt" ], reader.glob("docs/*.txt")
end

test "reader io provides size" do
tempfile = create_test_zip("hello.txt" => "Hello, World!")

reader = ZipFile::Reader.new(tempfile)
reader.read("hello.txt") do |io|
assert_equal 13, io.size
end
end

test "reader io supports rewind" do
tempfile = create_test_zip("hello.txt" => "Hello, World!")

reader = ZipFile::Reader.new(tempfile)
reader.read("hello.txt") do |io|
first_read = io.read
io.rewind
second_read = io.read

assert_equal first_read, second_read
end
end

test "reader io tracks eof" do
tempfile = create_test_zip("hello.txt" => "Hello")

reader = ZipFile::Reader.new(tempfile)
reader.read("hello.txt") do |io|
assert_not io.eof?
io.read
assert io.eof?
end
end

private
def create_test_zip(files)
tempfile = Tempfile.new([ "test", ".zip" ])
tempfile.binmode

writer = ZipFile::Writer.new(tempfile)
files.each { |path, content| writer.add_file(path, content) }
writer.close

tempfile.rewind
tempfile
end
end