adsp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/LICENSE +21 -0
- data/README.md +300 -0
- data/lib/adsp/error.rb +14 -0
- data/lib/adsp/file.rb +76 -0
- data/lib/adsp/option.rb +51 -0
- data/lib/adsp/stream/abstract.rb +206 -0
- data/lib/adsp/stream/delegates.rb +39 -0
- data/lib/adsp/stream/raw/abstract.rb +69 -0
- data/lib/adsp/stream/raw/compressor.rb +110 -0
- data/lib/adsp/stream/raw/decompressor.rb +80 -0
- data/lib/adsp/stream/raw/native_compressor.rb +58 -0
- data/lib/adsp/stream/raw/native_decompressor.rb +44 -0
- data/lib/adsp/stream/reader.rb +234 -0
- data/lib/adsp/stream/reader_helpers.rb +219 -0
- data/lib/adsp/stream/stat.rb +80 -0
- data/lib/adsp/stream/writer.rb +206 -0
- data/lib/adsp/stream/writer_helpers.rb +102 -0
- data/lib/adsp/string.rb +58 -0
- data/lib/adsp/validation.rb +46 -0
- data/lib/adsp/version.rb +7 -0
- data/lib/adsp.rb +8 -0
- data/test/common.rb +108 -0
- data/test/coverage_helper.rb +18 -0
- data/test/file.test.rb +120 -0
- data/test/minitest.rb +20 -0
- data/test/mock/common.rb +57 -0
- data/test/mock/file.rb +60 -0
- data/test/mock/stream/raw/compressor.rb +20 -0
- data/test/mock/stream/raw/decompressor.rb +20 -0
- data/test/mock/stream/raw/native_compressor.rb +82 -0
- data/test/mock/stream/raw/native_decompressor.rb +70 -0
- data/test/mock/stream/reader.rb +18 -0
- data/test/mock/stream/writer.rb +18 -0
- data/test/mock/string.rb +44 -0
- data/test/option.rb +66 -0
- data/test/stream/abstract.rb +125 -0
- data/test/stream/minitar.test.rb +50 -0
- data/test/stream/raw/abstract.rb +45 -0
- data/test/stream/raw/compressor.test.rb +166 -0
- data/test/stream/raw/decompressor.test.rb +166 -0
- data/test/stream/reader.test.rb +643 -0
- data/test/stream/reader_helpers.test.rb +421 -0
- data/test/stream/writer.test.rb +610 -0
- data/test/stream/writer_helpers.test.rb +267 -0
- data/test/string.test.rb +95 -0
- data/test/validation.rb +71 -0
- data/test/version.test.rb +18 -0
- metadata +274 -0
    
        data/test/option.rb
    ADDED
    
    | @@ -0,0 +1,66 @@ | |
| 1 | 
            +
            # Abstract data stream processor.
         | 
| 2 | 
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require "ocg"
         | 
| 5 | 
            +
            require "adsp/option"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            require_relative "validation"
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            module ADSP
         | 
| 10 | 
            +
              module Test
         | 
| 11 | 
            +
                module Option
         | 
| 12 | 
            +
                  private_class_method def self.get_common_invalid_options(buffer_length_names, &block)
         | 
| 13 | 
            +
                    Validation::INVALID_HASHES.each(&block)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    buffer_length_names.each do |name|
         | 
| 16 | 
            +
                      (Validation::INVALID_NOT_NEGATIVE_INTEGERS - [nil]).each do |invalid_integer|
         | 
| 17 | 
            +
                        yield({ name => invalid_integer })
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def self.get_invalid_compressor_options(buffer_length_names, &block)
         | 
| 23 | 
            +
                    get_common_invalid_options buffer_length_names, &block
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  def self.get_invalid_decompressor_options(buffer_length_names, &block)
         | 
| 27 | 
            +
                    get_common_invalid_options buffer_length_names, &block
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  # -----
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  # "0" means default buffer length.
         | 
| 33 | 
            +
                  BUFFER_LENGTHS = [
         | 
| 34 | 
            +
                    0,
         | 
| 35 | 
            +
                    2
         | 
| 36 | 
            +
                  ]
         | 
| 37 | 
            +
                  .freeze
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  BOOLS = [
         | 
| 40 | 
            +
                    true,
         | 
| 41 | 
            +
                    false
         | 
| 42 | 
            +
                  ]
         | 
| 43 | 
            +
                  .freeze
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  private_class_method def self.get_buffer_length_option_generator(buffer_length_names)
         | 
| 46 | 
            +
                    OCG.new(
         | 
| 47 | 
            +
                      buffer_length_names.to_h { |name| [name, self::BUFFER_LENGTHS] }
         | 
| 48 | 
            +
                    )
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  def self.get_compressor_options_generator(buffer_length_names)
         | 
| 52 | 
            +
                    get_buffer_length_option_generator buffer_length_names
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  def self.get_compatible_decompressor_options(compressor_options, buffer_length_name_mapping, &_block)
         | 
| 56 | 
            +
                    decompressor_options = {}
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    buffer_length_name_mapping.each do |compressor_name, decompressor_name|
         | 
| 59 | 
            +
                      decompressor_options[decompressor_name] = compressor_options[compressor_name]
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    yield decompressor_options
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
            end
         | 
| @@ -0,0 +1,125 @@ | |
| 1 | 
            +
            # Abstract data stream processor.
         | 
| 2 | 
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require "fcntl"
         | 
| 5 | 
            +
            require "stringio"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            require_relative "../common"
         | 
| 8 | 
            +
            require_relative "../minitest"
         | 
| 9 | 
            +
            require_relative "../validation"
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            module ADSP
         | 
| 12 | 
            +
              module Test
         | 
| 13 | 
            +
                module Stream
         | 
| 14 | 
            +
                  class Abstract < Minitest::Test
         | 
| 15 | 
            +
                    SOURCE_PATH = Common::SOURCE_PATH
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    def test_invalid_initialize
         | 
| 18 | 
            +
                      (Validation::INVALID_STRINGS - [nil] + Validation::INVALID_ENCODINGS).each do |invalid_encoding|
         | 
| 19 | 
            +
                        assert_raises ValidateError do
         | 
| 20 | 
            +
                          target.new ::StringIO.new, {}, :external_encoding => invalid_encoding
         | 
| 21 | 
            +
                        end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                        assert_raises ValidateError do
         | 
| 24 | 
            +
                          target.new ::StringIO.new, {}, :internal_encoding => invalid_encoding
         | 
| 25 | 
            +
                        end
         | 
| 26 | 
            +
                      end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      (Validation::INVALID_HASHES - [nil]).each do |invalid_hash|
         | 
| 29 | 
            +
                        assert_raises ValidateError do
         | 
| 30 | 
            +
                          target.new ::StringIO.new, {}, :transcode_options => invalid_hash
         | 
| 31 | 
            +
                        end
         | 
| 32 | 
            +
                      end
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    def test_invalid_set_encoding
         | 
| 36 | 
            +
                      instance = target.new ::StringIO.new
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                      (Validation::INVALID_STRINGS - [nil] + Validation::INVALID_ENCODINGS).each do |invalid_encoding|
         | 
| 39 | 
            +
                        assert_raises ValidateError do
         | 
| 40 | 
            +
                          instance.set_encoding invalid_encoding
         | 
| 41 | 
            +
                        end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                        assert_raises ValidateError do
         | 
| 44 | 
            +
                          instance.set_encoding ::Encoding::BINARY, invalid_encoding
         | 
| 45 | 
            +
                        end
         | 
| 46 | 
            +
                      end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      Validation::INVALID_ENCODINGS.each do |invalid_encoding|
         | 
| 49 | 
            +
                        assert_raises ValidateError do
         | 
| 50 | 
            +
                          instance.set_encoding "#{::Encoding::BINARY}:#{invalid_encoding}"
         | 
| 51 | 
            +
                        end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                        assert_raises ValidateError do
         | 
| 54 | 
            +
                          instance.set_encoding "#{invalid_encoding}:#{::Encoding::BINARY}"
         | 
| 55 | 
            +
                        end
         | 
| 56 | 
            +
                      end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                      (Validation::INVALID_HASHES - [nil]).each do |invalid_hash|
         | 
| 59 | 
            +
                        assert_raises ValidateError do
         | 
| 60 | 
            +
                          instance.set_encoding ::Encoding::BINARY, ::Encoding::BINARY, invalid_hash
         | 
| 61 | 
            +
                        end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                        assert_raises ValidateError do
         | 
| 64 | 
            +
                          instance.set_encoding "#{::Encoding::BINARY}:#{::Encoding::BINARY}", invalid_hash
         | 
| 65 | 
            +
                        end
         | 
| 66 | 
            +
                      end
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    def test_to_io
         | 
| 70 | 
            +
                      instance = target.new ::StringIO.new
         | 
| 71 | 
            +
                      assert_equal instance, instance.to_io
         | 
| 72 | 
            +
                    end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                    def test_io_delegates
         | 
| 75 | 
            +
                      ::File.open SOURCE_PATH, "wb+" do |file|
         | 
| 76 | 
            +
                        instance = target.new file
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                        instance.autoclose = true
         | 
| 79 | 
            +
                        assert_predicate instance, :autoclose?
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                        instance.binmode
         | 
| 82 | 
            +
                        assert_predicate instance, :binmode
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                        instance.close_on_exec = true
         | 
| 85 | 
            +
                        assert_predicate instance, :close_on_exec?
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                        # Fcntl is not available on windows.
         | 
| 88 | 
            +
                        if Fcntl.const_defined? :F_GETFL
         | 
| 89 | 
            +
                          stats = instance.fcntl Fcntl::F_GETFL, 0
         | 
| 90 | 
            +
                          refute_nil stats
         | 
| 91 | 
            +
                        end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                        instance.fdatasync
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                        fd = instance.fileno
         | 
| 96 | 
            +
                        refute_nil fd
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                        refute_predicate instance, :isatty
         | 
| 99 | 
            +
                        assert_nil instance.pid
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                        instance.sync = true
         | 
| 102 | 
            +
                        assert_predicate instance, :sync
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                        refute_nil instance.to_i
         | 
| 105 | 
            +
                        refute_predicate instance, :tty?
         | 
| 106 | 
            +
                      end
         | 
| 107 | 
            +
                    end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                    def test_stat
         | 
| 110 | 
            +
                      instance = target.new $stdout
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                      refute_predicate instance.stat, :file?
         | 
| 113 | 
            +
                      refute_predicate instance.stat, :pipe?
         | 
| 114 | 
            +
                      refute_predicate instance.stat, :socket?
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                    # -----
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                    protected def target
         | 
| 120 | 
            +
                      self.class::Target
         | 
| 121 | 
            +
                    end
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
              end
         | 
| 125 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            # Abstract data stream processor.
         | 
| 2 | 
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require "minitar"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            require_relative "../common"
         | 
| 7 | 
            +
            require_relative "../minitest"
         | 
| 8 | 
            +
            require_relative "../mock/stream/reader"
         | 
| 9 | 
            +
            require_relative "../mock/stream/writer"
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            module ADSP
         | 
| 12 | 
            +
              module Test
         | 
| 13 | 
            +
                module Stream
         | 
| 14 | 
            +
                  class MinitarTest < Minitest::Test
         | 
| 15 | 
            +
                    Reader = Mock::Stream::Reader
         | 
| 16 | 
            +
                    Writer = Mock::Stream::Writer
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    ARCHIVE_PATH = Common::ARCHIVE_PATH
         | 
| 19 | 
            +
                    LARGE_TEXTS  = Common::LARGE_TEXTS
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    def test_tar
         | 
| 22 | 
            +
                      Common.parallel LARGE_TEXTS do |text, worker_index|
         | 
| 23 | 
            +
                        archive_path = Common.get_path ARCHIVE_PATH, worker_index
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                        Writer.open archive_path do |writer|
         | 
| 26 | 
            +
                          Minitar::Writer.open writer do |tar|
         | 
| 27 | 
            +
                            tar.add_file_simple "file", :data => text
         | 
| 28 | 
            +
                          end
         | 
| 29 | 
            +
                        end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                        Reader.open archive_path do |reader|
         | 
| 32 | 
            +
                          Minitar::Reader.open reader do |tar|
         | 
| 33 | 
            +
                            tar.each_entry do |entry|
         | 
| 34 | 
            +
                              assert_equal "file", entry.name
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                              decompressed_text = entry.read
         | 
| 37 | 
            +
                              decompressed_text.force_encoding text.encoding
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                              assert_equal text, decompressed_text
         | 
| 40 | 
            +
                            end
         | 
| 41 | 
            +
                          end
         | 
| 42 | 
            +
                        end
         | 
| 43 | 
            +
                      end
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  Minitest << MinitarTest
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            # Abstract data stream processor.
         | 
| 2 | 
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require_relative "../../minitest"
         | 
| 5 | 
            +
            require_relative "../../validation"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module ADSP
         | 
| 8 | 
            +
              module Test
         | 
| 9 | 
            +
                module Stream
         | 
| 10 | 
            +
                  module Raw
         | 
| 11 | 
            +
                    class Abstract < Minitest::Test
         | 
| 12 | 
            +
                      NOOP_PROC = Validation::NOOP_PROC
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                      def test_invalid_flush
         | 
| 15 | 
            +
                        instance = target.new
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                        assert_raises ValidateError do
         | 
| 18 | 
            +
                          instance.flush
         | 
| 19 | 
            +
                        end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                        instance.close(&NOOP_PROC)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                        assert_raises UsedAfterCloseError do
         | 
| 24 | 
            +
                          instance.flush(&NOOP_PROC)
         | 
| 25 | 
            +
                        end
         | 
| 26 | 
            +
                      end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      def test_invalid_close
         | 
| 29 | 
            +
                        instance = target.new
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                        assert_raises ValidateError do
         | 
| 32 | 
            +
                          instance.close
         | 
| 33 | 
            +
                        end
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      # -----
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                      protected def target
         | 
| 39 | 
            +
                        self.class::Target
         | 
| 40 | 
            +
                      end
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -0,0 +1,166 @@ | |
| 1 | 
            +
            # Abstract data stream processor.
         | 
| 2 | 
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require_relative "abstract"
         | 
| 5 | 
            +
            require_relative "../../common"
         | 
| 6 | 
            +
            require_relative "../../minitest"
         | 
| 7 | 
            +
            require_relative "../../mock/stream/raw/compressor"
         | 
| 8 | 
            +
            require_relative "../../mock/string"
         | 
| 9 | 
            +
            require_relative "../../option"
         | 
| 10 | 
            +
            require_relative "../../validation"
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            module ADSP
         | 
| 13 | 
            +
              module Test
         | 
| 14 | 
            +
                module Stream
         | 
| 15 | 
            +
                  module Raw
         | 
| 16 | 
            +
                    class Compressor < Abstract
         | 
| 17 | 
            +
                      Target = Mock::Stream::Raw::Compressor
         | 
| 18 | 
            +
                      String = Mock::String
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                      TEXTS                 = Common::TEXTS
         | 
| 21 | 
            +
                      LARGE_TEXTS           = Common::LARGE_TEXTS
         | 
| 22 | 
            +
                      PORTION_LENGTHS       = Common::PORTION_LENGTHS
         | 
| 23 | 
            +
                      LARGE_PORTION_LENGTHS = Common::LARGE_PORTION_LENGTHS
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                      BUFFER_LENGTH_NAMES   = %i[destination_buffer_length].freeze
         | 
| 26 | 
            +
                      BUFFER_LENGTH_MAPPING = { :destination_buffer_length => :destination_buffer_length }.freeze
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      def test_invalid_initialize
         | 
| 29 | 
            +
                        get_invalid_compressor_options do |invalid_options|
         | 
| 30 | 
            +
                          assert_raises ValidateError do
         | 
| 31 | 
            +
                            Target.new invalid_options
         | 
| 32 | 
            +
                          end
         | 
| 33 | 
            +
                        end
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      def test_invalid_write
         | 
| 37 | 
            +
                        compressor = Target.new
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                        Validation::INVALID_STRINGS.each do |invalid_string|
         | 
| 40 | 
            +
                          assert_raises ValidateError do
         | 
| 41 | 
            +
                            compressor.write invalid_string, &NOOP_PROC
         | 
| 42 | 
            +
                          end
         | 
| 43 | 
            +
                        end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                        assert_raises ValidateError do
         | 
| 46 | 
            +
                          compressor.write ""
         | 
| 47 | 
            +
                        end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                        compressor.close(&NOOP_PROC)
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                        assert_raises UsedAfterCloseError do
         | 
| 52 | 
            +
                          compressor.write "", &NOOP_PROC
         | 
| 53 | 
            +
                        end
         | 
| 54 | 
            +
                      end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                      def test_texts
         | 
| 57 | 
            +
                        parallel_compressor_options do |compressor_options|
         | 
| 58 | 
            +
                          TEXTS.each do |text|
         | 
| 59 | 
            +
                            PORTION_LENGTHS.each do |portion_length|
         | 
| 60 | 
            +
                              compressed_buffer = ::StringIO.new
         | 
| 61 | 
            +
                              compressed_buffer.set_encoding ::Encoding::BINARY
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                              writer     = proc { |portion| compressed_buffer << portion }
         | 
| 64 | 
            +
                              compressor = Target.new compressor_options
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                              begin
         | 
| 67 | 
            +
                                source      = "".b
         | 
| 68 | 
            +
                                text_offset = 0
         | 
| 69 | 
            +
                                index       = 0
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                                loop do
         | 
| 72 | 
            +
                                  portion = text.byteslice text_offset, portion_length
         | 
| 73 | 
            +
                                  break if portion.nil?
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                                  text_offset += portion_length
         | 
| 76 | 
            +
                                  source << portion
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                                  bytes_written = compressor.write source, &writer
         | 
| 79 | 
            +
                                  source        = source.byteslice bytes_written, source.bytesize - bytes_written
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                                  compressor.flush(&writer) if index.even?
         | 
| 82 | 
            +
                                  index += 1
         | 
| 83 | 
            +
                                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                              ensure
         | 
| 86 | 
            +
                                refute_predicate compressor, :closed?
         | 
| 87 | 
            +
                                compressor.close(&writer)
         | 
| 88 | 
            +
                                assert_predicate compressor, :closed?
         | 
| 89 | 
            +
                              end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                              compressed_text = compressed_buffer.string
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                              get_compatible_decompressor_options compressor_options do |decompressor_options|
         | 
| 94 | 
            +
                                decompressed_text = String.decompress compressed_text, decompressor_options
         | 
| 95 | 
            +
                                decompressed_text.force_encoding text.encoding
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                                assert_equal text, decompressed_text
         | 
| 98 | 
            +
                              end
         | 
| 99 | 
            +
                            end
         | 
| 100 | 
            +
                          end
         | 
| 101 | 
            +
                        end
         | 
| 102 | 
            +
                      end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                      def test_large_texts
         | 
| 105 | 
            +
                        options_generator = OCG.new(
         | 
| 106 | 
            +
                          :text           => LARGE_TEXTS,
         | 
| 107 | 
            +
                          :portion_length => LARGE_PORTION_LENGTHS
         | 
| 108 | 
            +
                        )
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                        Common.parallel_options options_generator do |options|
         | 
| 111 | 
            +
                          text           = options[:text]
         | 
| 112 | 
            +
                          portion_length = options[:portion_length]
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                          compressed_buffer = ::StringIO.new
         | 
| 115 | 
            +
                          compressed_buffer.set_encoding ::Encoding::BINARY
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                          writer     = proc { |portion| compressed_buffer << portion }
         | 
| 118 | 
            +
                          compressor = Target.new
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                          begin
         | 
| 121 | 
            +
                            source      = "".b
         | 
| 122 | 
            +
                            text_offset = 0
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                            loop do
         | 
| 125 | 
            +
                              portion = text.byteslice text_offset, portion_length
         | 
| 126 | 
            +
                              break if portion.nil?
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                              text_offset += portion_length
         | 
| 129 | 
            +
                              source << portion
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                              bytes_written = compressor.write source, &writer
         | 
| 132 | 
            +
                              source        = source.byteslice bytes_written, source.bytesize - bytes_written
         | 
| 133 | 
            +
                            end
         | 
| 134 | 
            +
                          ensure
         | 
| 135 | 
            +
                            compressor.close(&writer)
         | 
| 136 | 
            +
                          end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                          compressed_text = compressed_buffer.string
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                          decompressed_text = String.decompress compressed_text
         | 
| 141 | 
            +
                          decompressed_text.force_encoding text.encoding
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                          assert_equal text, decompressed_text
         | 
| 144 | 
            +
                        end
         | 
| 145 | 
            +
                      end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                      # -----
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                      def get_invalid_compressor_options(&block)
         | 
| 150 | 
            +
                        Option.get_invalid_compressor_options BUFFER_LENGTH_NAMES, &block
         | 
| 151 | 
            +
                      end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                      def parallel_compressor_options(&block)
         | 
| 154 | 
            +
                        Common.parallel_options Option.get_compressor_options_generator(BUFFER_LENGTH_NAMES), &block
         | 
| 155 | 
            +
                      end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                      def get_compatible_decompressor_options(compressor_options, &block)
         | 
| 158 | 
            +
                        Option.get_compatible_decompressor_options compressor_options, BUFFER_LENGTH_MAPPING, &block
         | 
| 159 | 
            +
                      end
         | 
| 160 | 
            +
                    end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                    Minitest << Compressor
         | 
| 163 | 
            +
                  end
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
              end
         | 
| 166 | 
            +
            end
         | 
| @@ -0,0 +1,166 @@ | |
| 1 | 
            +
            # Abstract data stream processor.
         | 
| 2 | 
            +
            # Copyright (c) 2021 AUTHORS, MIT License.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require_relative "abstract"
         | 
| 5 | 
            +
            require_relative "../../common"
         | 
| 6 | 
            +
            require_relative "../../minitest"
         | 
| 7 | 
            +
            require_relative "../../mock/stream/raw/decompressor"
         | 
| 8 | 
            +
            require_relative "../../mock/string"
         | 
| 9 | 
            +
            require_relative "../../option"
         | 
| 10 | 
            +
            require_relative "../../validation"
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            module ADSP
         | 
| 13 | 
            +
              module Test
         | 
| 14 | 
            +
                module Stream
         | 
| 15 | 
            +
                  module Raw
         | 
| 16 | 
            +
                    class Decompressor < Abstract
         | 
| 17 | 
            +
                      Target = Mock::Stream::Raw::Decompressor
         | 
| 18 | 
            +
                      String = Mock::String
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                      TEXTS                 = Common::TEXTS
         | 
| 21 | 
            +
                      LARGE_TEXTS           = Common::LARGE_TEXTS
         | 
| 22 | 
            +
                      PORTION_LENGTHS       = Common::PORTION_LENGTHS
         | 
| 23 | 
            +
                      LARGE_PORTION_LENGTHS = Common::LARGE_PORTION_LENGTHS
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                      BUFFER_LENGTH_NAMES   = %i[destination_buffer_length].freeze
         | 
| 26 | 
            +
                      BUFFER_LENGTH_MAPPING = { :destination_buffer_length => :destination_buffer_length }.freeze
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      def test_invalid_initialize
         | 
| 29 | 
            +
                        get_invalid_decompressor_options do |invalid_options|
         | 
| 30 | 
            +
                          assert_raises ValidateError do
         | 
| 31 | 
            +
                            Target.new invalid_options
         | 
| 32 | 
            +
                          end
         | 
| 33 | 
            +
                        end
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      def test_invalid_read
         | 
| 37 | 
            +
                        decompressor = Target.new
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                        Validation::INVALID_STRINGS.each do |invalid_string|
         | 
| 40 | 
            +
                          assert_raises ValidateError do
         | 
| 41 | 
            +
                            decompressor.read invalid_string, &NOOP_PROC
         | 
| 42 | 
            +
                          end
         | 
| 43 | 
            +
                        end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                        assert_raises ValidateError do
         | 
| 46 | 
            +
                          decompressor.read ""
         | 
| 47 | 
            +
                        end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                        decompressor.close(&NOOP_PROC)
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                        assert_raises UsedAfterCloseError do
         | 
| 52 | 
            +
                          decompressor.read "", &NOOP_PROC
         | 
| 53 | 
            +
                        end
         | 
| 54 | 
            +
                      end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                      def test_texts
         | 
| 57 | 
            +
                        parallel_compressor_options do |compressor_options|
         | 
| 58 | 
            +
                          TEXTS.each do |text|
         | 
| 59 | 
            +
                            compressed_text = String.compress text, compressor_options
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                            PORTION_LENGTHS.each do |portion_length|
         | 
| 62 | 
            +
                              get_compatible_decompressor_options compressor_options do |decompressor_options|
         | 
| 63 | 
            +
                                decompressed_buffer = ::StringIO.new
         | 
| 64 | 
            +
                                decompressed_buffer.set_encoding ::Encoding::BINARY
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                                writer       = proc { |portion| decompressed_buffer << portion }
         | 
| 67 | 
            +
                                decompressor = Target.new decompressor_options
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                                begin
         | 
| 70 | 
            +
                                  source                 = "".b
         | 
| 71 | 
            +
                                  compressed_text_offset = 0
         | 
| 72 | 
            +
                                  index                  = 0
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                                  loop do
         | 
| 75 | 
            +
                                    portion = compressed_text.byteslice compressed_text_offset, portion_length
         | 
| 76 | 
            +
                                    break if portion.nil?
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                                    compressed_text_offset += portion_length
         | 
| 79 | 
            +
                                    source << portion
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                                    bytes_read = decompressor.read source, &writer
         | 
| 82 | 
            +
                                    source     = source.byteslice bytes_read, source.bytesize - bytes_read
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                                    decompressor.flush(&writer) if index.even?
         | 
| 85 | 
            +
                                    index += 1
         | 
| 86 | 
            +
                                  end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                                ensure
         | 
| 89 | 
            +
                                  refute_predicate decompressor, :closed?
         | 
| 90 | 
            +
                                  decompressor.close(&writer)
         | 
| 91 | 
            +
                                  assert_predicate decompressor, :closed?
         | 
| 92 | 
            +
                                end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                                decompressed_text = decompressed_buffer.string
         | 
| 95 | 
            +
                                decompressed_text.force_encoding text.encoding
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                                assert_equal text, decompressed_text
         | 
| 98 | 
            +
                              end
         | 
| 99 | 
            +
                            end
         | 
| 100 | 
            +
                          end
         | 
| 101 | 
            +
                        end
         | 
| 102 | 
            +
                      end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                      def test_large_texts
         | 
| 105 | 
            +
                        options_generator = OCG.new(
         | 
| 106 | 
            +
                          :text           => LARGE_TEXTS,
         | 
| 107 | 
            +
                          :portion_length => LARGE_PORTION_LENGTHS
         | 
| 108 | 
            +
                        )
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                        Common.parallel_options options_generator do |options|
         | 
| 111 | 
            +
                          text           = options[:text]
         | 
| 112 | 
            +
                          portion_length = options[:portion_length]
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                          compressed_text = String.compress text
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                          decompressed_buffer = ::StringIO.new
         | 
| 117 | 
            +
                          decompressed_buffer.set_encoding ::Encoding::BINARY
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                          writer       = proc { |portion| decompressed_buffer << portion }
         | 
| 120 | 
            +
                          decompressor = Target.new
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                          begin
         | 
| 123 | 
            +
                            source                 = "".b
         | 
| 124 | 
            +
                            compressed_text_offset = 0
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                            loop do
         | 
| 127 | 
            +
                              portion = compressed_text.byteslice compressed_text_offset, portion_length
         | 
| 128 | 
            +
                              break if portion.nil?
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                              compressed_text_offset += portion_length
         | 
| 131 | 
            +
                              source << portion
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                              bytes_read = decompressor.read source, &writer
         | 
| 134 | 
            +
                              source     = source.byteslice bytes_read, source.bytesize - bytes_read
         | 
| 135 | 
            +
                            end
         | 
| 136 | 
            +
                          ensure
         | 
| 137 | 
            +
                            decompressor.close(&writer)
         | 
| 138 | 
            +
                          end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                          decompressed_text = decompressed_buffer.string
         | 
| 141 | 
            +
                          decompressed_text.force_encoding text.encoding
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                          assert_equal text, decompressed_text
         | 
| 144 | 
            +
                        end
         | 
| 145 | 
            +
                      end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                      # -----
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                      def get_invalid_decompressor_options(&block)
         | 
| 150 | 
            +
                        Option.get_invalid_decompressor_options BUFFER_LENGTH_NAMES, &block
         | 
| 151 | 
            +
                      end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                      def parallel_compressor_options(&block)
         | 
| 154 | 
            +
                        Common.parallel_options Option.get_compressor_options_generator(BUFFER_LENGTH_NAMES), &block
         | 
| 155 | 
            +
                      end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                      def get_compatible_decompressor_options(compressor_options, &block)
         | 
| 158 | 
            +
                        Option.get_compatible_decompressor_options compressor_options, BUFFER_LENGTH_MAPPING, &block
         | 
| 159 | 
            +
                      end
         | 
| 160 | 
            +
                    end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                    Minitest << Decompressor
         | 
| 163 | 
            +
                  end
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
              end
         | 
| 166 | 
            +
            end
         |