hexdump 0.2.4 → 0.3.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 +4 -4
- data/.github/workflows/ruby.yml +3 -5
- data/ChangeLog.md +11 -0
- data/LICENSE.txt +1 -1
- data/README.md +99 -78
- data/benchmark.rb +47 -0
- data/gemspec.yml +8 -2
- data/hexdump.gemspec +1 -0
- data/lib/hexdump.rb +1 -1
- data/lib/hexdump/core_ext.rb +4 -0
- data/lib/hexdump/{extensions → core_ext}/file.rb +0 -0
- data/lib/hexdump/{extensions → core_ext}/io.rb +0 -0
- data/lib/hexdump/{extensions → core_ext}/string.rb +0 -0
- data/lib/hexdump/{extensions → core_ext}/string_io.rb +0 -0
- data/lib/hexdump/dumper.rb +61 -91
- data/lib/hexdump/extensions.rb +2 -4
- data/lib/hexdump/hexdump.rb +12 -21
- data/lib/hexdump/version.rb +1 -1
- data/spec/{extensions_spec.rb → core_ext_spec.rb} +2 -2
- data/spec/dumper_spec.rb +176 -107
- data/spec/hexdump_spec.rb +0 -1
- metadata +17 -12
- data/benchmarks/hexdump.rb +0 -45
    
        data/lib/hexdump/extensions.rb
    CHANGED
    
    
    
        data/lib/hexdump/hexdump.rb
    CHANGED
    
    | @@ -24,28 +24,25 @@ module Hexdump | |
| 24 24 | 
             
              # @param [#each_byte] data
         | 
| 25 25 | 
             
              #   The data to be hexdumped.
         | 
| 26 26 | 
             
              #
         | 
| 27 | 
            -
              # @param [ | 
| 28 | 
            -
              #   Additional options.
         | 
| 29 | 
            -
              #
         | 
| 30 | 
            -
              # @option options [Integer] :width (16)
         | 
| 27 | 
            +
              # @param [Integer] width (16)
         | 
| 31 28 | 
             
              #   The number of bytes to dump for each line.
         | 
| 32 29 | 
             
              #
         | 
| 33 | 
            -
              # @ | 
| 30 | 
            +
              # @param [Integer] endian (:little)
         | 
| 34 31 | 
             
              #   The endianness that the bytes are organized in. Supported endianness
         | 
| 35 32 | 
             
              #   include `:little` and `:big`.
         | 
| 36 33 | 
             
              #
         | 
| 37 | 
            -
              # @ | 
| 34 | 
            +
              # @param [Integer] word_size (1)
         | 
| 38 35 | 
             
              #   The number of bytes within a word.
         | 
| 39 36 | 
             
              #
         | 
| 40 | 
            -
              # @ | 
| 37 | 
            +
              # @param [Symbol, Integer] base (:hexadecimal)
         | 
| 41 38 | 
             
              #   The base to print bytes in. Supported bases include, `:hexadecimal`,
         | 
| 42 39 | 
             
              #   `:hex`, `16, `:decimal`, `:dec`, `10, `:octal`, `:oct`, `8`,
         | 
| 43 40 | 
             
              #   `:binary`, `:bin` and `2`.
         | 
| 44 41 | 
             
              #
         | 
| 45 | 
            -
              # @ | 
| 42 | 
            +
              # @param [Boolean] ascii (false)
         | 
| 46 43 | 
             
              #   Print ascii characters when possible.
         | 
| 47 44 | 
             
              #
         | 
| 48 | 
            -
              # @ | 
| 45 | 
            +
              # @param [#<<] output ($stdout)
         | 
| 49 46 | 
             
              #   The output to print the hexdump to.
         | 
| 50 47 | 
             
              #
         | 
| 51 48 | 
             
              # @yield [index,numeric,printable]
         | 
| @@ -68,14 +65,11 @@ module Hexdump | |
| 68 65 | 
             
              #   the `:output` value does not support the `#<<` method or
         | 
| 69 66 | 
             
              #   the `:base` value was unknown.
         | 
| 70 67 | 
             
              #
         | 
| 71 | 
            -
              def self.dump(data,options | 
| 72 | 
            -
                 | 
| 73 | 
            -
                dumper = Dumper.new(options)
         | 
| 68 | 
            +
              def self.dump(data, output: $stdout, **options,&block)
         | 
| 69 | 
            +
                dumper = Dumper.new(**options)
         | 
| 74 70 |  | 
| 75 | 
            -
                if block
         | 
| 76 | 
            -
             | 
| 77 | 
            -
                else
         | 
| 78 | 
            -
                  dumper.dump(data,output)
         | 
| 71 | 
            +
                if block then dumper.each(data,&block)
         | 
| 72 | 
            +
                else          dumper.dump(data,output)
         | 
| 79 73 | 
             
                end
         | 
| 80 74 |  | 
| 81 75 | 
             
                return nil
         | 
| @@ -84,12 +78,9 @@ module Hexdump | |
| 84 78 | 
             
              #
         | 
| 85 79 | 
             
              # Hexdumps the object.
         | 
| 86 80 | 
             
              #
         | 
| 87 | 
            -
              # @param [Hash] options
         | 
| 88 | 
            -
              #   Additional options.
         | 
| 89 | 
            -
              #
         | 
| 90 81 | 
             
              # @see Hexdump.dump
         | 
| 91 82 | 
             
              #
         | 
| 92 | 
            -
              def hexdump(options | 
| 93 | 
            -
                Hexdump.dump(self | 
| 83 | 
            +
              def hexdump(**options,&block)
         | 
| 84 | 
            +
                Hexdump.dump(self,**options,&block)
         | 
| 94 85 | 
             
              end
         | 
| 95 86 | 
             
            end
         | 
    
        data/lib/hexdump/version.rb
    CHANGED
    
    
    
        data/spec/dumper_spec.rb
    CHANGED
    
    | @@ -1,5 +1,4 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 | 
            -
             | 
| 3 2 | 
             
            require 'hexdump/dumper'
         | 
| 4 3 |  | 
| 5 4 | 
             
            describe Hexdump::Dumper do
         | 
| @@ -11,24 +10,23 @@ describe Hexdump::Dumper do | |
| 11 10 | 
             
              let(:print_chars) { ['h', 'e', 'l', 'l', 'o'] }
         | 
| 12 11 | 
             
              let(:data) { print_chars.join }
         | 
| 13 12 |  | 
| 14 | 
            -
               | 
| 15 | 
            -
                 | 
| 16 | 
            -
                   | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 13 | 
            +
              describe "#initialize" do
         | 
| 14 | 
            +
                it "should only accept known base: values" do
         | 
| 15 | 
            +
                  expect {
         | 
| 16 | 
            +
                    described_class.new(data, base: :foo)
         | 
| 17 | 
            +
                  }.to raise_error(ArgumentError)
         | 
| 18 | 
            +
                end
         | 
| 19 19 |  | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 20 | 
            +
                it "should only accept known endian: values" do
         | 
| 21 | 
            +
                  expect {
         | 
| 22 | 
            +
                    described_class.new(data, endian: :foo)
         | 
| 23 | 
            +
                  }.to raise_error(ArgumentError)
         | 
| 24 | 
            +
                end
         | 
| 24 25 | 
             
              end
         | 
| 25 26 |  | 
| 26 27 | 
             
              describe "each_word" do
         | 
| 27 28 | 
             
                let(:data) { 'ABAB' }
         | 
| 28 29 | 
             
                let(:bytes) { [0x41, 0x42, 0x41, 0x42] }
         | 
| 29 | 
            -
                let(:shorts_le) { [0x4241, 0x4241] }
         | 
| 30 | 
            -
                let(:shorts_be) { [0x4142, 0x4142] }
         | 
| 31 | 
            -
                let(:custom_words) { [0x414241, 0x42] }
         | 
| 32 30 |  | 
| 33 31 | 
             
                it "should check if the data defines '#each_byte'" do
         | 
| 34 32 | 
             
                  expect {
         | 
| @@ -40,22 +38,34 @@ describe Hexdump::Dumper do | |
| 40 38 | 
             
                  expect(subject.each_word(data).to_a).to be == bytes
         | 
| 41 39 | 
             
                end
         | 
| 42 40 |  | 
| 43 | 
            -
                 | 
| 44 | 
            -
                   | 
| 41 | 
            +
                context "when initialized with a custom word_size:" do
         | 
| 42 | 
            +
                  subject { described_class.new(word_size: 3) }
         | 
| 45 43 |  | 
| 46 | 
            -
                   | 
| 44 | 
            +
                  let(:custom_words) { [0x414241, 0x42] }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  it "should allow iterating over custom word-sizes" do
         | 
| 47 | 
            +
                    expect(subject.each_word(data).to_a).to be == custom_words
         | 
| 48 | 
            +
                  end
         | 
| 47 49 | 
             
                end
         | 
| 48 50 |  | 
| 49 | 
            -
                 | 
| 50 | 
            -
                   | 
| 51 | 
            +
                context "when initialized with default endian:" do
         | 
| 52 | 
            +
                  subject { described_class.new(word_size: 2) }
         | 
| 51 53 |  | 
| 52 | 
            -
                   | 
| 54 | 
            +
                  let(:shorts_le) { [0x4241, 0x4241] }
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  it "should iterate over little-endian words by default" do
         | 
| 57 | 
            +
                    expect(subject.each_word(data).to_a).to be == shorts_le
         | 
| 58 | 
            +
                  end
         | 
| 53 59 | 
             
                end
         | 
| 54 60 |  | 
| 55 | 
            -
                 | 
| 56 | 
            -
                   | 
| 61 | 
            +
                context "when initialized with endian: :big" do
         | 
| 62 | 
            +
                  subject { described_class.new(word_size: 2, endian: :big) }
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  let(:shorts_be) { [0x4142, 0x4142] }
         | 
| 57 65 |  | 
| 58 | 
            -
                   | 
| 66 | 
            +
                  it "should iterate over big-endian words" do
         | 
| 67 | 
            +
                    expect(subject.each_word(data).to_a).to be == shorts_be
         | 
| 68 | 
            +
                  end
         | 
| 59 69 | 
             
                end
         | 
| 60 70 | 
             
              end
         | 
| 61 71 |  | 
| @@ -74,72 +84,86 @@ describe Hexdump::Dumper do | |
| 74 84 | 
             
                end
         | 
| 75 85 |  | 
| 76 86 | 
             
                it "should provide the index within the data for each line" do
         | 
| 77 | 
            -
                  dumper = described_class.new(:width => 10)
         | 
| 78 87 | 
             
                  indices = []
         | 
| 79 88 |  | 
| 80 | 
            -
                   | 
| 89 | 
            +
                  subject.each('A' * (16 * 10)) do |index,hex,print|
         | 
| 81 90 | 
             
                    indices << index
         | 
| 82 91 | 
             
                  end
         | 
| 83 92 |  | 
| 84 | 
            -
                  expect(indices).to be == [0,  | 
| 93 | 
            +
                  expect(indices).to be == [0, 16, 32, 48, 64, 80, 96, 112, 128, 144]
         | 
| 85 94 | 
             
                end
         | 
| 86 95 |  | 
| 87 | 
            -
                 | 
| 88 | 
            -
                   | 
| 89 | 
            -
                  widths = []
         | 
| 96 | 
            +
                context "when initialized with a custom wdith:" do
         | 
| 97 | 
            +
                  let(:width) { 10 }
         | 
| 90 98 |  | 
| 91 | 
            -
                   | 
| 92 | 
            -
                    widths << hex.length
         | 
| 93 | 
            -
                  end
         | 
| 99 | 
            +
                  subject { described_class.new(width: width) }
         | 
| 94 100 |  | 
| 95 | 
            -
                   | 
| 96 | 
            -
             | 
| 101 | 
            +
                  it "should change the width, in bytes, of each line" do
         | 
| 102 | 
            +
                    widths = []
         | 
| 103 | 
            +
                    count  = 10
         | 
| 97 104 |  | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
                  string = chars.join
         | 
| 102 | 
            -
                  leading = ('A' * 100)
         | 
| 103 | 
            -
                  remainder = nil
         | 
| 105 | 
            +
                    subject.each('A' * (width * count)) do |index,hex,print|
         | 
| 106 | 
            +
                      widths << hex.length
         | 
| 107 | 
            +
                    end
         | 
| 104 108 |  | 
| 105 | 
            -
             | 
| 106 | 
            -
                    remainder = print
         | 
| 109 | 
            +
                    expect(widths).to be == ([width] * count)
         | 
| 107 110 | 
             
                  end
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                context "when there are leftover bytes" do
         | 
| 114 | 
            +
                  let(:width) { 10 }
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                  subject { described_class.new(width: width) }
         | 
| 108 117 |  | 
| 109 | 
            -
                   | 
| 118 | 
            +
                  let(:chars)   { ['B'] * 4 }
         | 
| 119 | 
            +
                  let(:string)  { chars.join }
         | 
| 120 | 
            +
                  let(:leading) { 'A' * 100 }
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                  it "should hexdump the remaining bytes" do
         | 
| 123 | 
            +
                    remainder = nil
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                    subject.each(leading + string) do |index,hex,print|
         | 
| 126 | 
            +
                      remainder = print
         | 
| 127 | 
            +
                    end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                    expect(remainder).to be == chars
         | 
| 130 | 
            +
                  end
         | 
| 110 131 | 
             
                end
         | 
| 111 132 |  | 
| 112 133 | 
             
                it "should provide the hexadecimal characters for each line" do
         | 
| 113 | 
            -
                  dumper = described_class.new(:width => 10)
         | 
| 114 134 | 
             
                  chars = []
         | 
| 135 | 
            +
                  length = (16 * 10)
         | 
| 115 136 |  | 
| 116 | 
            -
                   | 
| 137 | 
            +
                  subject.each(data * length) do |index,hex,print|
         | 
| 117 138 | 
             
                    chars += hex
         | 
| 118 139 | 
             
                  end
         | 
| 119 140 |  | 
| 120 | 
            -
                  expect(chars).to be == (hex_chars *  | 
| 141 | 
            +
                  expect(chars).to be == (hex_chars * length)
         | 
| 121 142 | 
             
                end
         | 
| 122 143 |  | 
| 123 | 
            -
                 | 
| 124 | 
            -
                   | 
| 125 | 
            -
                  chars = []
         | 
| 144 | 
            +
                context "when initialized with ascii: true" do
         | 
| 145 | 
            +
                  subject { described_class.new(ascii: true) }
         | 
| 126 146 |  | 
| 127 | 
            -
                   | 
| 128 | 
            -
                    chars  | 
| 129 | 
            -
             | 
| 147 | 
            +
                  it "should allow printing ASCII characters in place of hex characters" do
         | 
| 148 | 
            +
                    chars = []
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                    subject.each(data) do |index,hex,print|
         | 
| 151 | 
            +
                      chars += hex
         | 
| 152 | 
            +
                    end
         | 
| 130 153 |  | 
| 131 | 
            -
             | 
| 154 | 
            +
                    expect(chars).to be == print_chars
         | 
| 155 | 
            +
                  end
         | 
| 132 156 | 
             
                end
         | 
| 133 157 |  | 
| 134 158 | 
             
                it "should provide the print characters for each line" do
         | 
| 135 | 
            -
                  dumper = described_class.new(:width => 10)
         | 
| 136 159 | 
             
                  chars = []
         | 
| 160 | 
            +
                  length = (16 * 10)
         | 
| 137 161 |  | 
| 138 | 
            -
                   | 
| 162 | 
            +
                  subject.each(data * length) do |index,hex,print|
         | 
| 139 163 | 
             
                    chars += print
         | 
| 140 164 | 
             
                  end
         | 
| 141 165 |  | 
| 142 | 
            -
                  expect(chars).to be == (print_chars *  | 
| 166 | 
            +
                  expect(chars).to be == (print_chars * length)
         | 
| 143 167 | 
             
                end
         | 
| 144 168 |  | 
| 145 169 | 
             
                it "should map unprintable characters to '.'" do
         | 
| @@ -153,108 +177,153 @@ describe Hexdump::Dumper do | |
| 153 177 | 
             
                  expect(chars).to be == (['.'] * unprintable.length)
         | 
| 154 178 | 
             
                end
         | 
| 155 179 |  | 
| 156 | 
            -
                 | 
| 157 | 
            -
                   | 
| 158 | 
            -
                  chars = []
         | 
| 180 | 
            +
                context "when initialized with base: :decimal" do
         | 
| 181 | 
            +
                  subject { described_class.new(base: :decimal) }
         | 
| 159 182 |  | 
| 160 | 
            -
                   | 
| 161 | 
            -
                    chars  | 
| 162 | 
            -
                  end
         | 
| 183 | 
            +
                  it "should support dumping bytes in decimal format" do
         | 
| 184 | 
            +
                    chars = []
         | 
| 163 185 |  | 
| 164 | 
            -
             | 
| 186 | 
            +
                    subject.each(data) do |index,hex,print|
         | 
| 187 | 
            +
                      chars += hex
         | 
| 188 | 
            +
                    end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                    expect(chars).to be == decimal_chars
         | 
| 191 | 
            +
                  end
         | 
| 165 192 | 
             
                end
         | 
| 166 193 |  | 
| 167 | 
            -
                 | 
| 168 | 
            -
                   | 
| 169 | 
            -
                  chars = []
         | 
| 194 | 
            +
                context "when initialized with base: :octal" do
         | 
| 195 | 
            +
                  subject { described_class.new(base: :octal) }
         | 
| 170 196 |  | 
| 171 | 
            -
                   | 
| 172 | 
            -
                    chars  | 
| 173 | 
            -
             | 
| 197 | 
            +
                  it "should support dumping bytes in octal format" do
         | 
| 198 | 
            +
                    chars = []
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                    subject.each(data) do |index,hex,print|
         | 
| 201 | 
            +
                      chars += hex
         | 
| 202 | 
            +
                    end
         | 
| 174 203 |  | 
| 175 | 
            -
             | 
| 204 | 
            +
                    expect(chars).to be == octal_chars
         | 
| 205 | 
            +
                  end
         | 
| 176 206 | 
             
                end
         | 
| 177 207 |  | 
| 178 | 
            -
                 | 
| 179 | 
            -
                   | 
| 180 | 
            -
                  chars = []
         | 
| 208 | 
            +
                context "when initialized with base: :binary" do
         | 
| 209 | 
            +
                  subject { described_class.new(base: :binary) }
         | 
| 181 210 |  | 
| 182 | 
            -
                   | 
| 183 | 
            -
                    chars  | 
| 184 | 
            -
                  end
         | 
| 211 | 
            +
                  it "should support dumping bytes in binary format" do
         | 
| 212 | 
            +
                    chars = []
         | 
| 185 213 |  | 
| 186 | 
            -
             | 
| 214 | 
            +
                    subject.each(data) do |index,hex,print|
         | 
| 215 | 
            +
                      chars += hex
         | 
| 216 | 
            +
                    end
         | 
| 217 | 
            +
             | 
| 218 | 
            +
                    expect(chars).to be == binary_chars
         | 
| 219 | 
            +
                  end
         | 
| 187 220 | 
             
                end
         | 
| 188 221 |  | 
| 189 | 
            -
                context ": | 
| 222 | 
            +
                context "when initialized with word_size: and endian:" do
         | 
| 190 223 | 
             
                  let(:options) { {:word_size => 2, :endian => :little} }
         | 
| 191 | 
            -
             | 
| 192 224 | 
             
                  let(:hex_words) { ['6568', '6c6c', '006f'] }
         | 
| 193 | 
            -
                  let(:decimal_words) { ['25960', '27756', '  111'] }
         | 
| 194 | 
            -
                  let(:octal_words) { ['062550', '066154', '000157'] }
         | 
| 195 | 
            -
                  let(:binary_words) { ['0110010101101000', '0110110001101100', '0000000001101111'] }
         | 
| 196 225 |  | 
| 197 | 
            -
                   | 
| 198 | 
            -
             | 
| 226 | 
            +
                  subject { described_class.new(**options) }
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                  it "should dump words in hexadecimal by default" do
         | 
| 199 229 | 
             
                    words = []
         | 
| 200 230 |  | 
| 201 | 
            -
                     | 
| 231 | 
            +
                    subject.each(data) do |index,hex,print|
         | 
| 202 232 | 
             
                      words += hex
         | 
| 203 233 | 
             
                    end
         | 
| 204 234 |  | 
| 205 235 | 
             
                    expect(words).to be == hex_words
         | 
| 206 236 | 
             
                  end
         | 
| 207 237 |  | 
| 208 | 
            -
                   | 
| 209 | 
            -
                     | 
| 210 | 
            -
                    words = []
         | 
| 238 | 
            +
                  context "and base: :decimal" do
         | 
| 239 | 
            +
                    subject { described_class.new(base: :decimal, **options) }
         | 
| 211 240 |  | 
| 212 | 
            -
                     | 
| 213 | 
            -
                      words += dec
         | 
| 214 | 
            -
                    end
         | 
| 241 | 
            +
                    let(:decimal_words) { ['25960', '27756', '  111'] }
         | 
| 215 242 |  | 
| 216 | 
            -
                     | 
| 217 | 
            -
             | 
| 243 | 
            +
                    it "should dump words in decimal" do
         | 
| 244 | 
            +
                      words = []
         | 
| 218 245 |  | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 246 | 
            +
                      subject.each(data) do |index,dec,print|
         | 
| 247 | 
            +
                        words += dec
         | 
| 248 | 
            +
                      end
         | 
| 222 249 |  | 
| 223 | 
            -
             | 
| 224 | 
            -
                      words += oct
         | 
| 250 | 
            +
                      expect(words).to be == decimal_words
         | 
| 225 251 | 
             
                    end
         | 
| 252 | 
            +
                  end
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                  context "and base: :octal" do
         | 
| 255 | 
            +
                    subject { described_class.new(base: :octal, **options) }
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                    let(:octal_words) { ['062550', '066154', '000157'] }
         | 
| 258 | 
            +
             | 
| 259 | 
            +
                    it "should dump words in octal" do
         | 
| 260 | 
            +
                      words = []
         | 
| 226 261 |  | 
| 227 | 
            -
             | 
| 262 | 
            +
                      subject.each(data) do |index,oct,print|
         | 
| 263 | 
            +
                        words += oct
         | 
| 264 | 
            +
                      end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                      expect(words).to be == octal_words
         | 
| 267 | 
            +
                    end
         | 
| 228 268 | 
             
                  end
         | 
| 229 269 |  | 
| 230 | 
            -
                   | 
| 231 | 
            -
                     | 
| 232 | 
            -
             | 
| 270 | 
            +
                  context "and base: :binary" do
         | 
| 271 | 
            +
                    subject { described_class.new(base: :binary, **options) }
         | 
| 272 | 
            +
             | 
| 273 | 
            +
                    let(:binary_words) { ['0110010101101000', '0110110001101100', '0000000001101111'] }
         | 
| 274 | 
            +
             | 
| 275 | 
            +
                    it "should dump words in binary" do
         | 
| 276 | 
            +
                      words = []
         | 
| 233 277 |  | 
| 234 | 
            -
             | 
| 235 | 
            -
             | 
| 278 | 
            +
                      subject.each(data) do |index,bin,print|
         | 
| 279 | 
            +
                        words += bin
         | 
| 280 | 
            +
                      end
         | 
| 281 | 
            +
             | 
| 282 | 
            +
                      expect(words).to be == binary_words
         | 
| 236 283 | 
             
                    end
         | 
| 284 | 
            +
                  end
         | 
| 285 | 
            +
                end
         | 
| 237 286 |  | 
| 238 | 
            -
             | 
| 287 | 
            +
                it "must return the number of bytes read" do
         | 
| 288 | 
            +
                  length = 100
         | 
| 289 | 
            +
                  data   = 'A' * length
         | 
| 290 | 
            +
             | 
| 291 | 
            +
                  expect(subject.each(data) { |index,hex,print| }).to be == length
         | 
| 292 | 
            +
                end
         | 
| 293 | 
            +
             | 
| 294 | 
            +
                context "when no block is given" do
         | 
| 295 | 
            +
                  it "must return an Enumerator" do
         | 
| 296 | 
            +
                    expect(subject.each(data)).to be_kind_of(Enumerator)
         | 
| 239 297 | 
             
                  end
         | 
| 240 298 | 
             
                end
         | 
| 241 299 | 
             
              end
         | 
| 242 300 |  | 
| 243 301 | 
             
              describe "#dump" do
         | 
| 244 | 
            -
                it "should check if the  | 
| 302 | 
            +
                it "should check if the output supports the '#<<' method" do
         | 
| 245 303 | 
             
                  expect {
         | 
| 246 304 | 
             
                    subject.dump(data,Object.new)
         | 
| 247 305 | 
             
                  }.to raise_error(ArgumentError)
         | 
| 248 306 | 
             
                end
         | 
| 249 307 |  | 
| 308 | 
            +
                let(:index_format) { "%.8x" }
         | 
| 309 | 
            +
             | 
| 250 310 | 
             
                it "should append each line of the hexdump to the output" do
         | 
| 251 311 | 
             
                  lines = []
         | 
| 252 312 |  | 
| 253 313 | 
             
                  subject.dump(data,lines)
         | 
| 254 314 |  | 
| 255 | 
            -
                  expect(lines.length).to be( | 
| 315 | 
            +
                  expect(lines.length).to be(2)
         | 
| 316 | 
            +
                  expect(lines[0]).to start_with(index_format % 0)
         | 
| 256 317 | 
             
                  expect(lines[0]).to include(hex_chars.join(' '))
         | 
| 257 | 
            -
                  expect(lines[0]).to  | 
| 318 | 
            +
                  expect(lines[0]).to end_with("|#{print_chars.join}|#{$/}")
         | 
| 319 | 
            +
                end
         | 
| 320 | 
            +
             | 
| 321 | 
            +
                it "must always print the total number of bytes read on the last line" do
         | 
| 322 | 
            +
                  lines = []
         | 
| 323 | 
            +
             | 
| 324 | 
            +
                  subject.dump(data,lines)
         | 
| 325 | 
            +
             | 
| 326 | 
            +
                  expect(lines.last).to start_with(index_format % data.length)
         | 
| 258 327 | 
             
                end
         | 
| 259 328 | 
             
              end
         | 
| 260 329 | 
             
            end
         |