Skip to content

Commit

Permalink
Merge pull request #18 from felixbuenemann/refactor-io-wrappers
Browse files Browse the repository at this point in the history
Refactor IO Wrappers
  • Loading branch information
felixbuenemann authored Oct 30, 2017
2 parents d72ffc1 + 53123bf commit 6ef1a00
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 12 deletions.
13 changes: 8 additions & 5 deletions lib/xlsxtream/io/rubyzip.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
require "zip"
require "xlsxtream/errors"

module Xlsxtream
module IO
class RubyZip
def initialize(path_or_io)
@stream = path_or_io.respond_to? :reopen
path_or_io.binmode if path_or_io.respond_to? :binmode
@zos = Zip::OutputStream.new(path_or_io, @stream)
def initialize(io)
unless io.respond_to? :pos and io.respond_to? :pos=
raise Error, 'IO is not seekable'
end
io.binmode if io.respond_to? :binmode
stream = true
@zos = Zip::OutputStream.new(io, stream)
end

def <<(data)
Expand All @@ -20,7 +24,6 @@ def add_file(path)
def close
os = @zos.close_buffer
os.flush if os.respond_to? :flush
os.close if !@stream and os.respond_to? :close
end
end
end
Expand Down
18 changes: 11 additions & 7 deletions lib/xlsxtream/workbook.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
# encoding: utf-8
require "stringio"
require "xlsxtream/errors"
require "xlsxtream/xml"
require "xlsxtream/shared_string_table"
require "xlsxtream/workbook"
require "xlsxtream/io/rubyzip"
require "xlsxtream/io/directory"
require "xlsxtream/io/stream"

module Xlsxtream
class Workbook
Expand All @@ -22,8 +19,8 @@ class Workbook

class << self

def open(data = nil, options = {})
workbook = new(data, options)
def open(output = nil, options = {})
workbook = new(output, options)
if block_given?
begin
yield workbook
Expand All @@ -37,10 +34,16 @@ def open(data = nil, options = {})

end

def initialize(data = nil, options = {})
def initialize(output = nil, options = {})
output ||= StringIO.new
@options = options
io_wrapper = options[:io_wrapper] || IO::RubyZip
@io = io_wrapper.new(data || StringIO.new)
if output.is_a?(String) || !output.respond_to?(:<<)
@file = File.open(output, 'wb')
@io = io_wrapper.new(@file)
else
@io = io_wrapper.new(output)
end
@sst = SharedStringTable.new
@worksheets = Hash.new { |hash, name| hash[name] = hash.size + 1 }
end
Expand Down Expand Up @@ -74,6 +77,7 @@ def close
write_root_rels
write_content_types
@io.close
@file.close if @file
nil
end

Expand Down
32 changes: 32 additions & 0 deletions test/xlsxtream/io/directory_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require 'test_helper'
require 'xlsxtream/io/directory'
require 'pathname'

module Xlsxtream
module IO
class DirectoryTest < Minitest::Test

def test_writes_of_multiple_files
Dir.mktmpdir do |dir|
io = Xlsxtream::IO::Directory.new(dir)
io.add_file("book1.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook />'
io.add_file("book2.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook>'
io << '</workbook>'
io.add_file("empty.txt")
io.add_file("another.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><another />'
io.close

dir = Pathname(dir)
assert_equal '', dir.join('empty.txt').read
assert_equal '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook />', dir.join('book1.xml').read
assert_equal '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook></workbook>', dir.join('book2.xml').read
assert_equal '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><another />', dir.join('another.xml').read
end

end
end
end
end
30 changes: 30 additions & 0 deletions test/xlsxtream/io/hash_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'test_helper'
require 'xlsxtream/io/hash'

module Xlsxtream
module IO
class HashTest < Minitest::Test

def test_writes_of_multiple_files
buffer = StringIO.new

io = Xlsxtream::IO::Hash.new(buffer)
io.add_file("book1.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook />'
io.add_file("book2.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook>'
io << '</workbook>'
io.add_file("empty.txt")
io.add_file("another.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><another />'
io.close

file_contents = io.to_h
assert_equal '', file_contents['empty.txt']
assert_equal '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook />', file_contents['book1.xml']
assert_equal '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook></workbook>', file_contents['book2.xml']
assert_equal '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><another />', file_contents['another.xml']
end
end
end
end
40 changes: 40 additions & 0 deletions test/xlsxtream/io/rubyzip_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'test_helper'
require 'xlsxtream/io/rubyzip'
require 'zip'

module Xlsxtream
module IO
class RubyZipTest < Minitest::Test

def test_writes_of_multiple_files
zip_buf = Tempfile.new('ztio-test')

io = Xlsxtream::IO::RubyZip.new(zip_buf)
io.add_file("book1.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook />'
io.add_file("book2.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook>'
io << '</workbook>'
io.add_file("empty.txt")
io.add_file("another.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><another />'
io.close

zip_buf.rewind

file_contents = {}
::Zip::File.open(zip_buf) do |zip_file|
zip_file.each do |entry|
file_contents[entry.name] = entry.get_input_stream.read
end
end
assert_equal '', file_contents['empty.txt']
assert_equal '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook />', file_contents['book1.xml']
assert_equal '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook></workbook>', file_contents['book2.xml']
assert_equal '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><another />', file_contents['another.xml']
ensure
zip_buf.close! if zip_buf
end
end
end
end
36 changes: 36 additions & 0 deletions test/xlsxtream/io/stream_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'test_helper'
require 'xlsxtream/io/stream'

module Xlsxtream
module IO
class StreamTest < Minitest::Test

def test_writes_of_multiple_files
buffer = StringIO.new

io = Xlsxtream::IO::Stream.new(buffer)
io.add_file("book1.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook />'
io.add_file("book2.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook>'
io << '</workbook>'
io.add_file("empty.txt")
io.add_file("another.xml")
io << '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><another />'
io.close

file_contents = buffer.string
assert_equal <<-EOF, file_contents
book1.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook />
book2.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook></workbook>
empty.txt
another.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><another />
EOF
end
end
end
end
17 changes: 17 additions & 0 deletions test/xlsxtream/workbook_test.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
require 'test_helper'
require 'tempfile'
require 'xlsxtream/workbook'
require 'xlsxtream/io/hash'

module Xlsxtream
class WorksheetTest < Minitest::Test

def test_workbook_from_path
tempfile = Tempfile.new('xlsxtream')
Workbook.open(tempfile.path) {}
refute_equal 0, tempfile.size
ensure
tempfile.close! if tempfile
end

def test_workbook_from_io
tempfile = Tempfile.new('xlsxtream')
Workbook.open(tempfile) {}
refute_equal 0, tempfile.size
ensure
tempfile.close! if tempfile
end

def test_empty_workbook
iow_spy = io_wrapper_spy
Workbook.open(nil, :io_wrapper => iow_spy) {}
Expand Down

0 comments on commit 6ef1a00

Please sign in to comment.