hexdump 0.3.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +5 -6
  3. data/.gitignore +1 -0
  4. data/.yardopts +1 -1
  5. data/ChangeLog.md +79 -6
  6. data/Gemfile +3 -0
  7. data/LICENSE.txt +1 -1
  8. data/README.md +500 -137
  9. data/benchmark.rb +29 -22
  10. data/gemspec.yml +2 -1
  11. data/hexdump.gemspec +1 -4
  12. data/lib/hexdump/chars.rb +46 -0
  13. data/lib/hexdump/core_ext/file.rb +68 -6
  14. data/lib/hexdump/core_ext/io.rb +2 -2
  15. data/lib/hexdump/core_ext/kernel.rb +5 -0
  16. data/lib/hexdump/core_ext/string.rb +2 -2
  17. data/lib/hexdump/core_ext/string_io.rb +2 -2
  18. data/lib/hexdump/core_ext.rb +5 -4
  19. data/lib/hexdump/format_string.rb +43 -0
  20. data/lib/hexdump/hexdump.rb +766 -75
  21. data/lib/hexdump/mixin.rb +192 -0
  22. data/lib/hexdump/module_methods.rb +132 -0
  23. data/lib/hexdump/numeric/binary.rb +55 -0
  24. data/lib/hexdump/numeric/char_or_int.rb +95 -0
  25. data/lib/hexdump/numeric/decimal.rb +56 -0
  26. data/lib/hexdump/numeric/exceptions.rb +11 -0
  27. data/lib/hexdump/numeric/hexadecimal.rb +59 -0
  28. data/lib/hexdump/numeric/octal.rb +55 -0
  29. data/lib/hexdump/numeric.rb +5 -0
  30. data/lib/hexdump/reader.rb +313 -0
  31. data/lib/hexdump/theme/ansi.rb +82 -0
  32. data/lib/hexdump/theme/rule.rb +159 -0
  33. data/lib/hexdump/theme.rb +61 -0
  34. data/lib/hexdump/type.rb +233 -0
  35. data/lib/hexdump/types.rb +108 -0
  36. data/lib/hexdump/version.rb +1 -1
  37. data/lib/hexdump.rb +14 -3
  38. data/spec/chars_spec.rb +76 -0
  39. data/spec/core_ext_spec.rb +10 -6
  40. data/spec/format_string_spec.rb +22 -0
  41. data/spec/hexdump_class_spec.rb +1708 -0
  42. data/spec/hexdump_module_spec.rb +23 -0
  43. data/spec/mixin_spec.rb +37 -0
  44. data/spec/numeric/binary_spec.rb +239 -0
  45. data/spec/numeric/char_or_int_spec.rb +210 -0
  46. data/spec/numeric/decimal_spec.rb +317 -0
  47. data/spec/numeric/hexadecimal_spec.rb +320 -0
  48. data/spec/numeric/octal_spec.rb +239 -0
  49. data/spec/reader_spec.rb +866 -0
  50. data/spec/spec_helper.rb +2 -0
  51. data/spec/theme/ansi_spec.rb +242 -0
  52. data/spec/theme/rule_spec.rb +199 -0
  53. data/spec/theme_spec.rb +94 -0
  54. data/spec/type_spec.rb +317 -0
  55. data/spec/types_spec.rb +904 -0
  56. metadata +42 -12
  57. data/.gemtest +0 -0
  58. data/lib/hexdump/dumper.rb +0 -419
  59. data/lib/hexdump/extensions.rb +0 -2
  60. data/spec/dumper_spec.rb +0 -329
  61. data/spec/hexdump_spec.rb +0 -30
data/spec/spec_helper.rb CHANGED
@@ -1 +1,3 @@
1
1
  require 'rspec'
2
+ require 'simplecov'
3
+ SimpleCov.start
@@ -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