hexdump 0.3.0 → 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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +68 -2
  3. data/Gemfile +1 -0
  4. data/README.md +486 -135
  5. data/benchmark.rb +29 -22
  6. data/lib/hexdump/chars.rb +46 -0
  7. data/lib/hexdump/core_ext/file.rb +68 -6
  8. data/lib/hexdump/core_ext/io.rb +2 -2
  9. data/lib/hexdump/core_ext/kernel.rb +7 -0
  10. data/lib/hexdump/core_ext/string.rb +2 -2
  11. data/lib/hexdump/core_ext/string_io.rb +2 -2
  12. data/lib/hexdump/core_ext.rb +1 -0
  13. data/lib/hexdump/format_string.rb +43 -0
  14. data/lib/hexdump/hexdump.rb +768 -75
  15. data/lib/hexdump/mixin.rb +198 -0
  16. data/lib/hexdump/module_methods.rb +132 -0
  17. data/lib/hexdump/numeric/binary.rb +55 -0
  18. data/lib/hexdump/numeric/char_or_int.rb +90 -0
  19. data/lib/hexdump/numeric/decimal.rb +56 -0
  20. data/lib/hexdump/numeric/exceptions.rb +11 -0
  21. data/lib/hexdump/numeric/hexadecimal.rb +59 -0
  22. data/lib/hexdump/numeric/octal.rb +55 -0
  23. data/lib/hexdump/numeric.rb +5 -0
  24. data/lib/hexdump/reader.rb +314 -0
  25. data/lib/hexdump/theme/ansi.rb +81 -0
  26. data/lib/hexdump/theme/rule.rb +159 -0
  27. data/lib/hexdump/theme.rb +61 -0
  28. data/lib/hexdump/type.rb +232 -0
  29. data/lib/hexdump/types.rb +108 -0
  30. data/lib/hexdump/version.rb +1 -1
  31. data/lib/hexdump.rb +12 -1
  32. data/spec/chars_spec.rb +76 -0
  33. data/spec/core_ext_spec.rb +10 -6
  34. data/spec/hexdump_class_spec.rb +1708 -0
  35. data/spec/hexdump_module_spec.rb +23 -0
  36. data/spec/mixin_spec.rb +37 -0
  37. data/spec/numeric/binary_spec.rb +239 -0
  38. data/spec/numeric/char_or_int_spec.rb +210 -0
  39. data/spec/numeric/decimal_spec.rb +317 -0
  40. data/spec/numeric/hexadecimal_spec.rb +320 -0
  41. data/spec/numeric/octal_spec.rb +239 -0
  42. data/spec/reader_spec.rb +863 -0
  43. data/spec/theme/ansi_spec.rb +242 -0
  44. data/spec/theme/rule_spec.rb +199 -0
  45. data/spec/theme_spec.rb +94 -0
  46. data/spec/type_spec.rb +317 -0
  47. data/spec/types_spec.rb +904 -0
  48. metadata +39 -10
  49. data/.gemtest +0 -0
  50. data/lib/hexdump/dumper.rb +0 -419
  51. data/spec/dumper_spec.rb +0 -329
  52. data/spec/hexdump_spec.rb +0 -30
@@ -0,0 +1,242 @@
1
+ require 'spec_helper'
2
+ require 'hexdump/theme/ansi'
3
+
4
+ describe Hexdump::Theme::ANSI do
5
+ describe "RESET" do
6
+ subject { described_class::RESET }
7
+
8
+ it "must equal '\\e[0m'" do
9
+ expect(subject).to eq("\e[0m")
10
+ end
11
+ end
12
+
13
+ describe "PARAMETERS" do
14
+ subject { described_class::PARAMETERS }
15
+
16
+ describe ":reset" do
17
+ subject { super()[:reset] }
18
+
19
+ it "must equal '\\e[0m'" do
20
+ expect(subject).to eq("\e[0m")
21
+ end
22
+ end
23
+
24
+ describe ":bold" do
25
+ subject { super()[:bold] }
26
+
27
+ it "must equal '\\e[1m'" do
28
+ expect(subject).to eq("\e[1m")
29
+ end
30
+ end
31
+
32
+ describe ":faint" do
33
+ subject { super()[:faint] }
34
+
35
+ it "must equal '\\e[2m'" do
36
+ expect(subject).to eq("\e[2m")
37
+ end
38
+ end
39
+
40
+ describe ":italic" do
41
+ subject { super()[:italic] }
42
+
43
+ it "must equal '\\e[3m'" do
44
+ expect(subject).to eq("\e[3m")
45
+ end
46
+ end
47
+
48
+ describe ":underline" do
49
+ subject { super()[:underline] }
50
+
51
+ it "must equal '\\e[4m'" do
52
+ expect(subject).to eq("\e[4m")
53
+ end
54
+ end
55
+
56
+ describe ":invert" do
57
+ subject { super()[:invert] }
58
+
59
+ it "must equal '\\e[7m'" do
60
+ expect(subject).to eq("\e[7m")
61
+ end
62
+ end
63
+
64
+ describe ":strike" do
65
+ subject { super()[:strike] }
66
+
67
+ it "must equal '\\e[9m'" do
68
+ expect(subject).to eq("\e[9m")
69
+ end
70
+ end
71
+
72
+ describe ":black" do
73
+ subject { super()[:black] }
74
+
75
+ it "must equal '\\e[30m'" do
76
+ expect(subject).to eq("\e[30m")
77
+ end
78
+ end
79
+
80
+ describe ":red" do
81
+ subject { super()[:red] }
82
+
83
+ it "must equal '\\e[31m'" do
84
+ expect(subject).to eq("\e[31m")
85
+ end
86
+ end
87
+
88
+ describe ":green" do
89
+ subject { super()[:green] }
90
+
91
+ it "must equal '\\e[32m'" do
92
+ expect(subject).to eq("\e[32m")
93
+ end
94
+ end
95
+
96
+ describe ":yellow" do
97
+ subject { super()[:yellow] }
98
+
99
+ it "must equal '\\e[33m'" do
100
+ expect(subject).to eq("\e[33m")
101
+ end
102
+ end
103
+
104
+ describe ":blue" do
105
+ subject { super()[:blue] }
106
+
107
+ it "must equal '\\e[34m'" do
108
+ expect(subject).to eq("\e[34m")
109
+ end
110
+ end
111
+
112
+ describe ":magenta" do
113
+ subject { super()[:magenta] }
114
+
115
+ it "must equal '\\e[35m'" do
116
+ expect(subject).to eq("\e[35m")
117
+ end
118
+ end
119
+
120
+ describe ":cyan" do
121
+ subject { super()[:cyan] }
122
+
123
+ it "must equal '\\e[36m'" do
124
+ expect(subject).to eq("\e[36m")
125
+ end
126
+ end
127
+
128
+ describe ":white" do
129
+ subject { super()[:white] }
130
+
131
+ it "must equal '\\e[37m'" do
132
+ expect(subject).to eq("\e[37m")
133
+ end
134
+ end
135
+
136
+ describe ":on_black" do
137
+ subject { super()[:on_black] }
138
+
139
+ it "must equal '\\e[40m'" do
140
+ expect(subject).to eq("\e[40m")
141
+ end
142
+ end
143
+
144
+ describe ":on_red" do
145
+ subject { super()[:on_red] }
146
+
147
+ it "must equal '\\e[41m'" do
148
+ expect(subject).to eq("\e[41m")
149
+ end
150
+ end
151
+
152
+ describe ":on_green" do
153
+ subject { super()[:on_green] }
154
+
155
+ it "must equal '\\e[42m'" do
156
+ expect(subject).to eq("\e[42m")
157
+ end
158
+ end
159
+
160
+ describe ":on_yellow" do
161
+ subject { super()[:on_yellow] }
162
+
163
+ it "must equal '\\e[43m'" do
164
+ expect(subject).to eq("\e[43m")
165
+ end
166
+ end
167
+
168
+ describe ":on_blue" do
169
+ subject { super()[:on_blue] }
170
+
171
+ it "must equal '\\e[44m'" do
172
+ expect(subject).to eq("\e[44m")
173
+ end
174
+ end
175
+
176
+ describe ":on_magenta" do
177
+ subject { super()[:on_magenta] }
178
+
179
+ it "must equal '\\e[45m'" do
180
+ expect(subject).to eq("\e[45m")
181
+ end
182
+ end
183
+
184
+ describe ":on_cyan" do
185
+ subject { super()[:on_cyan] }
186
+
187
+ it "must equal '\\e[46m'" do
188
+ expect(subject).to eq("\e[46m")
189
+ end
190
+ end
191
+
192
+ describe ":on_white" do
193
+ subject { super()[:on_white] }
194
+
195
+ it "must equal '\\e[47m'" do
196
+ expect(subject).to eq("\e[47m")
197
+ end
198
+ end
199
+ end
200
+
201
+ describe "#initialize" do
202
+ context "when given one parameters name" do
203
+ let(:parameters) { :bold }
204
+
205
+ subject { described_class.new(parameters) }
206
+
207
+ it "must set #parameters to that parameters name" do
208
+ expect(subject.parameters).to eq(parameters)
209
+ end
210
+
211
+ it "must set #ansi to that parameters's ANSI string" do
212
+ expect(subject.string).to eq(described_class::PARAMETERS[:bold])
213
+ end
214
+ end
215
+
216
+ context "when given multiple parameters names" do
217
+ let(:parameters) { [:bold, :green] }
218
+
219
+ subject { described_class.new(parameters) }
220
+
221
+ it "must set #parameters to that parameters names" do
222
+ expect(subject.parameters).to eq(parameters)
223
+ end
224
+
225
+ it "must set #ansi to the combined parameters's ANSI strings" do
226
+ expect(subject.string).to eq(
227
+ described_class::PARAMETERS[:bold] + described_class::PARAMETERS[:green]
228
+ )
229
+ end
230
+ end
231
+
232
+ context "when given an unknown parameters name" do
233
+ let(:parameter) { :foo }
234
+
235
+ it do
236
+ expect {
237
+ described_class.new(parameter)
238
+ }.to raise_error(ArgumentError,"unknown ANSI parameter: #{parameter}")
239
+ end
240
+ end
241
+ end
242
+ end
@@ -0,0 +1,199 @@
1
+ require 'spec_helper'
2
+ require 'hexdump/theme/rule'
3
+
4
+ describe Hexdump::Theme::Rule do
5
+ describe "#initialize" do
6
+ context "when no style is given" do
7
+ subject { described_class.new }
8
+
9
+ it "must set #style to nil" do
10
+ expect(subject.style).to be(nil)
11
+ end
12
+ end
13
+
14
+ context "when given a style" do
15
+ let(:style) { :bold }
16
+
17
+ subject { described_class.new(style: style) }
18
+
19
+ it "must initialize #style based on the given style" do
20
+ expect(subject.style).to be_kind_of(Hexdump::Theme::ANSI)
21
+ expect(subject.style.parameters).to eq(style)
22
+ end
23
+ end
24
+
25
+ context "when given no highlights: keyword argument" do
26
+ it "must initialize #highlight_strings to {}" do
27
+ expect(subject.highlight_strings).to eq({})
28
+ end
29
+
30
+ it "must initialize #highlight_regexps to {}" do
31
+ expect(subject.highlight_regexps).to eq({})
32
+ end
33
+ end
34
+
35
+ context "when given the highlights: keyword argument" do
36
+ let(:highlights) { {/[a-f]/ => :green, '00' => :red} }
37
+
38
+ subject { described_class.new(highlights: highlights) }
39
+
40
+ it "must populate #highlight_strings with the String keys" do
41
+ expect(subject.highlight_strings['00']).to be_kind_of(Hexdump::Theme::ANSI)
42
+ expect(subject.highlight_strings['00'].parameters).to eq(:red)
43
+ end
44
+
45
+ it "must populate #highlight_regexps with the Regexp keys" do
46
+ expect(subject.highlight_regexps[/[a-f]/]).to be_kind_of(Hexdump::Theme::ANSI)
47
+ expect(subject.highlight_regexps[/[a-f]/].parameters).to eq(:green)
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "#highlights" do
53
+ let(:highlights) { {/[a-f]/ => :green, '00' => :red} }
54
+
55
+ subject { described_class.new(highlights: highlights) }
56
+
57
+ it "must combine #highlight_strings and #highlight_regexps" do
58
+ expect(subject.highlights).to eq(subject.highlight_strings.merge(subject.highlight_regexps))
59
+ end
60
+ end
61
+
62
+ describe "#highlight" do
63
+ context "when given a String pattern" do
64
+ let(:pattern) { '00' }
65
+ let(:style) { :red }
66
+
67
+ before { subject.highlight(pattern,style) }
68
+
69
+ it "must populate #highlight_strings with the given String" do
70
+ expect(subject.highlight_strings[pattern]).to be_kind_of(Hexdump::Theme::ANSI)
71
+ expect(subject.highlight_strings[pattern].parameters).to eq(style)
72
+ end
73
+ end
74
+
75
+ context "when given a Regexp pattern" do
76
+ let(:pattern) { /[a-f]/ }
77
+ let(:style) { :green }
78
+
79
+ before { subject.highlight(pattern,style) }
80
+
81
+ it "must populate #highlight_regexps with the given Regexp" do
82
+ expect(subject.highlight_regexps[pattern]).to be_kind_of(Hexdump::Theme::ANSI)
83
+ expect(subject.highlight_regexps[pattern].parameters).to eq(style)
84
+ end
85
+ end
86
+
87
+ context "when not given a String or Regexp" do
88
+ let(:pattern) { Object.new }
89
+ let(:style) { :red }
90
+
91
+ it do
92
+ expect {
93
+ subject.highlight(pattern,style)
94
+ }.to raise_error(ArgumentError,"pattern must be a String or Regexp: #{pattern.inspect}")
95
+ end
96
+ end
97
+ end
98
+
99
+ describe "#apply" do
100
+ let(:string) { "00f0" }
101
+
102
+ let(:highlights) { {'00' => :faint, /[a-f]/ => :green} }
103
+
104
+ let(:reset) { Hexdump::Theme::ANSI::RESET }
105
+ let(:red) { Hexdump::Theme::ANSI::PARAMETERS[:red] }
106
+ let(:green) { Hexdump::Theme::ANSI::PARAMETERS[:green] }
107
+
108
+ context "when there are #highlight_strings rules" do
109
+ let(:highlights) { {"00" => :red} }
110
+
111
+ subject { described_class.new(highlights: highlights) }
112
+
113
+ context "and the whole string matches a #highlight_strings rule" do
114
+ let(:string) { '00' }
115
+
116
+ it "must highlight the whole string" do
117
+ expect(subject.apply(string)).to eq("#{red}#{string}#{reset}")
118
+ end
119
+ end
120
+
121
+ context "but the string does not match any of the rules" do
122
+ let(:string) { 'ff' }
123
+
124
+ it "must return the given String" do
125
+ expect(subject.apply(string)).to eq(string)
126
+ end
127
+ end
128
+ end
129
+
130
+ context "when there are #highlight_regexps rules" do
131
+ let(:highlights) { {/f/ => :green} }
132
+
133
+ subject { described_class.new(highlights: highlights) }
134
+
135
+ context "and the whole string matches a #highlight_strings rule" do
136
+ let(:string) { '00f0' }
137
+
138
+ it "must highlight the matching substrings within the string" do
139
+ expect(subject.apply(string)).to eq("00#{green}f#{reset}0")
140
+ end
141
+
142
+ context "and #style is initialized" do
143
+ subject do
144
+ described_class.new(
145
+ style: :cyan,
146
+ highlights: highlights
147
+ )
148
+ end
149
+
150
+ it "must re-enable the default style after resetting the highlighting" do
151
+ expect(subject.apply(string)).to include("#{green}f#{reset}#{subject.style}")
152
+ end
153
+
154
+ context "when the beginning of the string is not highlighted" do
155
+ let(:string) { "0f" }
156
+
157
+ it "must prepend the string with the default style" do
158
+ expect(subject.apply(string)).to eq("#{subject.style}0#{green}f#{reset}")
159
+ end
160
+ end
161
+
162
+ context "when the end of the string is not highlighted" do
163
+ let(:string) { "f0" }
164
+
165
+ it "must append ANSI reset to the end of the string" do
166
+ expect(subject.apply(string)).to eq("#{green}f#{reset}#{subject.style}0#{reset}")
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ context "but the string does not match any of the rules" do
173
+ let(:string) { '0000' }
174
+
175
+ it "must return the given String" do
176
+ expect(subject.apply(string)).to eq(string)
177
+ end
178
+ end
179
+ end
180
+
181
+ context "when #style is initialized" do
182
+ let(:style) { :cyan }
183
+
184
+ subject { described_class.new(style: style) }
185
+
186
+ it "must wrap the given string with the style's ANSI string and reset" do
187
+ expect(subject.apply(string)).to eq("#{subject.style}#{string}#{reset}")
188
+ end
189
+ end
190
+
191
+ context "when #style is not initialized" do
192
+ let(:string) { 'ff' }
193
+
194
+ it "must return the given String" do
195
+ expect(subject.apply(string)).to eq(string)
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+ require 'hexdump/theme'
3
+
4
+ describe Hexdump::Theme do
5
+ describe "#initialize" do
6
+ it "must initialize #index" do
7
+ expect(subject.index).to be_kind_of(Hexdump::Theme::Rule)
8
+ end
9
+
10
+ it "must initialize #numeric" do
11
+ expect(subject.numeric).to be_kind_of(Hexdump::Theme::Rule)
12
+ end
13
+
14
+ it "must initialize #chars" do
15
+ expect(subject.chars).to be_kind_of(Hexdump::Theme::Rule)
16
+ end
17
+
18
+ context "when given a style Hash" do
19
+ let(:index_style) { :white }
20
+ let(:numeric_style) { :cyan }
21
+ let(:chars_style) { :blue }
22
+
23
+ subject do
24
+ described_class.new(
25
+ style: {
26
+ index: index_style,
27
+ numeric: numeric_style,
28
+ chars: chars_style
29
+ }
30
+ )
31
+ end
32
+
33
+ it "must initialize #index" do
34
+ expect(subject.index).to be_kind_of(Hexdump::Theme::Rule)
35
+ end
36
+
37
+ it "must initialize #index.style" do
38
+ expect(subject.index.style.parameters).to eq(index_style)
39
+ end
40
+
41
+ it "must initialize #numeric" do
42
+ expect(subject.numeric).to be_kind_of(Hexdump::Theme::Rule)
43
+ end
44
+
45
+ it "must initialize #numeric.style" do
46
+ expect(subject.numeric.style.parameters).to eq(numeric_style)
47
+ end
48
+
49
+ it "must initialize #chars" do
50
+ expect(subject.chars).to be_kind_of(Hexdump::Theme::Rule)
51
+ end
52
+
53
+ it "must initialize #chars.style" do
54
+ expect(subject.chars.style.parameters).to eq(chars_style)
55
+ end
56
+ end
57
+
58
+ context "when given a highlight Hash" do
59
+ let(:index_pattern) { /00$/ }
60
+ let(:index_highlight) { :white }
61
+ let(:index_highlights) { {index_pattern => index_highlight} }
62
+
63
+ let(:numeric_pattern) { '00' }
64
+ let(:numeric_highlight) { :faint }
65
+ let(:numeric_highlights) { {numeric_pattern => numeric_highlight} }
66
+
67
+ let(:chars_pattern) { /A-Z/ }
68
+ let(:chars_highlight) { :bold }
69
+ let(:chars_highlights) { {chars_pattern => chars_highlight} }
70
+
71
+ subject do
72
+ described_class.new(
73
+ highlights: {
74
+ index: index_highlights,
75
+ numeric: numeric_highlights,
76
+ chars: chars_highlights
77
+ }
78
+ )
79
+ end
80
+
81
+ it "must initialize #index.highlights" do
82
+ expect(subject.index.highlights[index_pattern].parameters).to eq(index_highlight)
83
+ end
84
+
85
+ it "must initialize #numeric.highlights" do
86
+ expect(subject.numeric.highlights[numeric_pattern].parameters).to eq(numeric_highlight)
87
+ end
88
+
89
+ it "must initialize #chars.highlights" do
90
+ expect(subject.chars.highlights[chars_pattern].parameters).to eq(chars_highlight)
91
+ end
92
+ end
93
+ end
94
+ end