mirror of
https://github.com/usetrmnl/terminus.git
synced 2026-08-13 14:29:27 -07:00
Added zipper
Wraps `Zip::OutputStream` to create an in memory zip file in order to answer a monad result for further processing. Milestone: minor
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "dry/monads"
|
||||
require "initable"
|
||||
require "refinements/string"
|
||||
require "zip"
|
||||
|
||||
module Terminus
|
||||
module Aspects
|
||||
# A monadic compressor of zip file content.
|
||||
class Zipper
|
||||
include Initable[io: Zip::OutputStream]
|
||||
include Dry::Monads[:result]
|
||||
|
||||
using Refinements::String
|
||||
|
||||
def self.compress manifest, buffer
|
||||
manifest.each do |name, content|
|
||||
buffer.put_next_entry name
|
||||
buffer.write content
|
||||
end
|
||||
end
|
||||
|
||||
def call manifest
|
||||
io.write_buffer { self.class.compress manifest, it }
|
||||
.tap(&:rewind)
|
||||
.then { Success it }
|
||||
rescue TypeError, Zip::Error => error
|
||||
Failure error.message.up
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "hanami_helper"
|
||||
|
||||
RSpec.describe Terminus::Aspects::Zipper do
|
||||
subject(:zipper) { described_class.new }
|
||||
|
||||
describe "#call" do
|
||||
let(:manifest) { {"one.txt" => "One", "two.txt" => "Two"} }
|
||||
|
||||
it "create zip file in memory" do
|
||||
io = zipper.call(manifest).value!
|
||||
|
||||
content = Zip::File.open_buffer(io).each.with_object({}) do |entry, attributes|
|
||||
attributes[entry.name] = entry.get_input_stream.read
|
||||
end
|
||||
|
||||
expect(content).to eq(manifest)
|
||||
end
|
||||
|
||||
it "answers StringIO instance" do
|
||||
expect(zipper.call(manifest)).to match(Success(kind_of(StringIO)))
|
||||
end
|
||||
|
||||
it "answers failure with invalid type" do
|
||||
expect(zipper.call({bogus: Object.new})).to be_failure(
|
||||
"No implicit conversion of Object into String"
|
||||
)
|
||||
end
|
||||
|
||||
it "answers failure with zip error" do
|
||||
io = class_double Zip::OutputStream
|
||||
zipper = described_class.new(io:)
|
||||
|
||||
allow(io).to receive(:write_buffer).and_raise(Zip::Error, "Danger!")
|
||||
|
||||
expect(zipper.call({test: "test"})).to be_failure("Danger!")
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user