aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--spec/services/meta_zip_data_spec.rb55
-rw-r--r--spec/support/helpers/tree_walker.rb15
-rw-r--r--spec/support/zip_support.rb25
-rw-r--r--spec/support/zip_support/create_zip_data.rb70
4 files changed, 165 insertions, 0 deletions
diff --git a/spec/services/meta_zip_data_spec.rb b/spec/services/meta_zip_data_spec.rb
new file mode 100644
index 000000000..1cbfee008
--- /dev/null
+++ b/spec/services/meta_zip_data_spec.rb
@@ -0,0 +1,55 @@
+# Convenience meta spec to debug potential bugs in zip support helpers
+# uncomment run and check files in `zip_fixtures_path`
+#
+# It also describes what the two helpers do and therefore facilitates the usage of
+#
+# * `make_zip` and
+# * `make_zip_from_tree
+#
+RSpec.describe 'ZipData', type: [:zip, :meta] do
+
+ # let( :zip_file ){ zip_fixtures_path('xxx.zip') }
+ # let( :tmp_output ){ zip_fixtures_path('tmp') }
+
+ # before do
+ # clear_all_zip_fixtures!
+ # Dir.mkdir(tmp_output)
+ # end
+
+ # context 'a simple archive' do
+ # let( :zip_data ){ make_zip "xxx.zip", archive_content }
+ # let( :archive_content ){ {
+ # 'hello.txt' => 'hello',
+ # 'subdir/too.txt' => 'in a subdir'
+ # } }
+
+ # it 'handmade: plausibility and manual check' do
+ # zip_data.write_to(zip_file)
+ # %x{unzip -oqq #{zip_file} -d #{tmp_output}}
+ # archive_content.each do | rel_path, content |
+ # expect(File.read(File.join(tmp_output, rel_path))).to eq(content)
+ # end
+ # end
+ # end
+
+ # context 'archive from dir tree' do
+ # let( :dir ){ fixtures_path 'meta_zip' }
+ # let( :zip_data ){ make_zip_from_tree dir }
+
+ # let( :archive_content ){ {
+ # 'one/alpha' => "alpha\n",
+ # 'two/beta' => "beta\n",
+ # 'two/subdir/gamma' => "gamma\n"
+ # } }
+
+ # it 'directory: plausibility and manual check' do
+ # zip_data.write_to(zip_file)
+ # %x{unzip -oqq #{zip_file} -d #{tmp_output}}
+ # archive_content.each do | rel_path, content |
+ # expect(File.read(File.join(tmp_output, rel_path))).to eq(content)
+ # end
+ # end
+
+ # end
+
+end
diff --git a/spec/support/helpers/tree_walker.rb b/spec/support/helpers/tree_walker.rb
new file mode 100644
index 000000000..b86c3a8e1
--- /dev/null
+++ b/spec/support/helpers/tree_walker.rb
@@ -0,0 +1,15 @@
+module TreeWalker extend self
+ MAX_LEVEL = 5
+ def walk_tree path, max_level: MAX_LEVEL, level: 0, yield_dirs: :no, &blk
+ raise RuntimeError, "too many levels in tree walk, > #{max_level}" if level > max_level
+ Dir.glob(File.join(path, '*')) do | file |
+ if File.directory?( file )
+ blk.(:dir, file) if yield_dirs == :before
+ walk_tree(file, max_level: max_level, level: level.succ, yield_dirs: yield_dirs, &blk)
+ blk.(:dir, file) if yield_dirs == :after
+ else
+ blk.(:file, file)
+ end
+ end
+ end
+end
diff --git a/spec/support/zip_support.rb b/spec/support/zip_support.rb
new file mode 100644
index 000000000..3d9b2f97c
--- /dev/null
+++ b/spec/support/zip_support.rb
@@ -0,0 +1,25 @@
+require_relative 'helpers/tree_walker'
+module ZipSupport
+
+ module Helper extend self
+ def remove
+ -> filetype, path do
+ filetype == :file ? File.unlink(path) : Dir.unlink(path)
+ end
+ end
+ end
+
+ def zip_fixtures_path(file_name)
+ fixtures_path(File.join('zip', file_name))
+ end
+
+ def clear_all_zip_fixtures! relpath = ''
+ raise ArgumentError, 'up dir not allowed (..)' if %r{\.\.} === relpath
+ TreeWalker.walk_tree zip_fixtures_path(relpath), yield_dirs: :after, &Helper.remove
+ end
+end
+
+RSpec.configure do |conf|
+ conf.include ZipSupport, type: :zip
+end
+
diff --git a/spec/support/zip_support/create_zip_data.rb b/spec/support/zip_support/create_zip_data.rb
new file mode 100644
index 000000000..250d67f74
--- /dev/null
+++ b/spec/support/zip_support/create_zip_data.rb
@@ -0,0 +1,70 @@
+require_relative '../helpers/tree_walker'
+module ZipSupport
+ module CreateZipData
+
+ class ZipData < Struct.new(:name, :data)
+
+ def write_to file
+ File.write(file, data)
+ end
+
+ end
+
+ class Implementation
+
+ attr_reader :name, :prefix, :zip
+
+ def initialize name
+ @name = name
+ @prefix = "#{name}/"
+ @zip = ZipData.new(name, '')
+ end
+
+ def make_from names_to_content_map
+ os = Zip::OutputStream.write_buffer do | zio |
+ names_to_content_map.each(&add_entries(zio))
+ end
+ zip.data = os.string
+ zip
+ end
+
+ def make_from_tree
+ os = Zip::OutputStream.write_buffer do | zio |
+ TreeWalker.walk_tree(name, &add_entry(zio))
+ end
+ zip.data = os.string
+ zip
+ end
+
+ private
+
+ def add_entry zio
+ -> _, path do
+ rel_path = path.sub(prefix, '')
+ zio.put_next_entry(rel_path)
+ zio.write(File.read(path))
+ end
+ end
+
+ def add_entries zio
+ -> name, content do
+ zio.put_next_entry(name)
+ zio.write(content)
+ end
+ end
+ end
+
+
+ def make_zip(name, names_to_content_map = {})
+ Implementation.new(name).make_from(names_to_content_map)
+ end
+
+ def make_zip_from_tree(dir)
+ Implementation.new(dir).make_from_tree
+ end
+ end
+end
+
+RSpec.configure do |conf|
+ conf.include ZipSupport::CreateZipData, type: :zip
+end