diff options
| -rw-r--r-- | spec/services/meta_zip_data_spec.rb | 55 | ||||
| -rw-r--r-- | spec/support/helpers/tree_walker.rb | 15 | ||||
| -rw-r--r-- | spec/support/zip_support.rb | 25 | ||||
| -rw-r--r-- | spec/support/zip_support/create_zip_data.rb | 70 | 
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 | 
