ruby-nmap 0.9.3 → 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 +5 -5
- data/.document +1 -0
- data/.editorconfig +11 -0
- data/.github/workflows/ruby.yml +31 -0
- data/ChangeLog.md +122 -67
- data/Gemfile +11 -5
- data/LICENSE.txt +1 -1
- data/README.md +88 -50
- data/Rakefile +8 -3
- data/UPGRADING.md +47 -0
- data/gemspec.yml +6 -6
- data/lib/nmap/command.rb +765 -0
- data/lib/nmap/version.rb +1 -1
- data/lib/nmap/xml/address.rb +38 -0
- data/lib/nmap/xml/cpe/url.rb +80 -0
- data/lib/nmap/xml/cpe.rb +47 -0
- data/lib/nmap/xml/hop.rb +22 -0
- data/lib/nmap/xml/host.rb +546 -0
- data/lib/nmap/xml/host_script.rb +26 -0
- data/lib/nmap/xml/hostname.rb +44 -0
- data/lib/nmap/xml/ip_id_sequence.rb +26 -0
- data/lib/nmap/xml/os.rb +131 -0
- data/lib/nmap/xml/os_class.rb +86 -0
- data/lib/nmap/xml/os_match.rb +22 -0
- data/lib/nmap/xml/port.rb +114 -0
- data/lib/nmap/xml/postscript.rb +26 -0
- data/lib/nmap/xml/prescript.rb +26 -0
- data/lib/nmap/xml/run_stat.rb +22 -0
- data/lib/nmap/xml/scan.rb +38 -0
- data/lib/nmap/xml/scan_task.rb +55 -0
- data/lib/nmap/xml/scanner.rb +22 -0
- data/lib/nmap/xml/script.rb +110 -0
- data/lib/nmap/xml/scripts.rb +33 -0
- data/lib/nmap/xml/sequence.rb +52 -0
- data/lib/nmap/xml/service.rb +172 -0
- data/lib/nmap/xml/status.rb +22 -0
- data/lib/nmap/xml/tcp_sequence.rb +48 -0
- data/lib/nmap/xml/tcp_ts_sequence.rb +26 -0
- data/lib/nmap/xml/traceroute.rb +73 -0
- data/lib/nmap/xml/uptime.rb +22 -0
- data/lib/nmap/xml.rb +46 -44
- data/ruby-nmap.gemspec +38 -83
- data/spec/command_spec.rb +726 -0
- data/spec/fixtures/down_host_scan.xml +16 -0
- data/spec/{local_scan.xml → fixtures/local_scan.xml} +1 -1
- data/spec/{scan.xml → fixtures/scan.xml} +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/{address_spec.rb → xml/address_spec.rb} +2 -2
- data/spec/{cpe → xml/cpe}/url_spec.rb +1 -1
- data/spec/{cpe_examples.rb → xml/cpe_examples.rb} +1 -1
- data/spec/{hop_spec.rb → xml/hop_spec.rb} +2 -2
- data/spec/{host_script_spec.rb → xml/host_script_spec.rb} +2 -2
- data/spec/{host_spec.rb → xml/host_spec.rb} +12 -8
- data/spec/{hostname_spec.rb → xml/hostname_spec.rb} +2 -2
- data/spec/{ip_id_sequence_spec.rb → xml/ip_id_sequence_spec.rb} +3 -3
- data/spec/{os_class_spec.rb → xml/os_class_spec.rb} +3 -3
- data/spec/{os_match_spec.rb → xml/os_match_spec.rb} +2 -2
- data/spec/{os_spec.rb → xml/os_spec.rb} +3 -3
- data/spec/{port_spec.rb → xml/port_spec.rb} +10 -5
- data/spec/{postscript_spec.rb → xml/postscript_spec.rb} +2 -2
- data/spec/{prescript_spec.rb → xml/prescript_spec.rb} +2 -2
- data/spec/{run_stat_spec.rb → xml/run_stat_spec.rb} +2 -2
- data/spec/{scan_spec.rb → xml/scan_spec.rb} +2 -2
- data/spec/{scan_task_spec.rb → xml/scan_task_spec.rb} +6 -6
- data/spec/{scanner_spec.rb → xml/scanner_spec.rb} +3 -3
- data/spec/xml/script_spec.rb +137 -0
- data/spec/xml/scripts_examples.rb +19 -0
- data/spec/{sequence_examples.rb → xml/sequence_examples.rb} +1 -0
- data/spec/{service_spec.rb → xml/service_spec.rb} +31 -5
- data/spec/{status_spec.rb → xml/status_spec.rb} +4 -3
- data/spec/{tcp_sequence_spec.rb → xml/tcp_sequence_spec.rb} +3 -3
- data/spec/{tcp_ts_sequence_spec.rb → xml/tcp_ts_sequence_spec.rb} +3 -3
- data/spec/{traceroute_spec.rb → xml/traceroute_spec.rb} +3 -3
- data/spec/{uptime_spec.rb → xml/uptime_spec.rb} +2 -2
- data/spec/xml_spec.rb +93 -45
- metadata +78 -99
- data/.travis.yml +0 -14
- data/lib/nmap/address.rb +0 -34
- data/lib/nmap/cpe/url.rb +0 -78
- data/lib/nmap/cpe.rb +0 -45
- data/lib/nmap/hop.rb +0 -20
- data/lib/nmap/host.rb +0 -586
- data/lib/nmap/host_script.rb +0 -18
- data/lib/nmap/hostname.rb +0 -42
- data/lib/nmap/ip_id_sequence.rb +0 -24
- data/lib/nmap/os.rb +0 -127
- data/lib/nmap/os_class.rb +0 -82
- data/lib/nmap/os_match.rb +0 -18
- data/lib/nmap/port.rb +0 -99
- data/lib/nmap/postscript.rb +0 -16
- data/lib/nmap/prescript.rb +0 -16
- data/lib/nmap/program.rb +0 -102
- data/lib/nmap/run_stat.rb +0 -20
- data/lib/nmap/scan.rb +0 -34
- data/lib/nmap/scan_task.rb +0 -50
- data/lib/nmap/scanner.rb +0 -18
- data/lib/nmap/scripts.rb +0 -71
- data/lib/nmap/sequence.rb +0 -50
- data/lib/nmap/service.rb +0 -170
- data/lib/nmap/status.rb +0 -18
- data/lib/nmap/task.rb +0 -381
- data/lib/nmap/tcp_sequence.rb +0 -46
- data/lib/nmap/tcp_ts_sequence.rb +0 -22
- data/lib/nmap/traceroute.rb +0 -71
- data/lib/nmap/uptime.rb +0 -20
- data/spec/scripts_examples.rb +0 -35
- data/spec/task_spec.rb +0 -150
|
@@ -0,0 +1,726 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'nmap/command'
|
|
3
|
+
|
|
4
|
+
describe Nmap::Command do
|
|
5
|
+
describe described_class::Port do
|
|
6
|
+
describe "#validate" do
|
|
7
|
+
context "when given an Integer" do
|
|
8
|
+
let(:value) { 443 }
|
|
9
|
+
|
|
10
|
+
it "must return true" do
|
|
11
|
+
expect(subject.validate(value)).to be(true)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "but it's less than 1" do
|
|
15
|
+
let(:value) { 0 }
|
|
16
|
+
|
|
17
|
+
it "must return [false, \"(...) not within the range of acceptable values (1..65535)\"]" do
|
|
18
|
+
expect(subject.validate(value)).to eq(
|
|
19
|
+
[false, "(#{value.inspect}) not within the range of acceptable values (1..65535)"]
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "but it's greater than 65535" do
|
|
25
|
+
let(:value) { 65536 }
|
|
26
|
+
|
|
27
|
+
it "must return [false, \"(...) not within the range of acceptable values (1..65535)\"]" do
|
|
28
|
+
expect(subject.validate(value)).to eq(
|
|
29
|
+
[false, "(#{value.inspect}) not within the range of acceptable values (1..65535)"]
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "when given a String" do
|
|
36
|
+
context "and it's a number" do
|
|
37
|
+
let(:value) { '443' }
|
|
38
|
+
|
|
39
|
+
it "must return true" do
|
|
40
|
+
expect(subject.validate(value)).to be(true)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "but it's less than 1" do
|
|
44
|
+
let(:value) { '0' }
|
|
45
|
+
|
|
46
|
+
it "must return [false, \"(...) not within the range of acceptable values (1..65535)\"]" do
|
|
47
|
+
expect(subject.validate(value)).to eq(
|
|
48
|
+
[false, "(#{value.inspect}) not within the range of acceptable values (1..65535)"]
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "but it's greater than 65535" do
|
|
54
|
+
let(:value) { '65536' }
|
|
55
|
+
|
|
56
|
+
it "must return [false, \"(...) not within the range of acceptable values (1..65535)\"]" do
|
|
57
|
+
expect(subject.validate(value)).to eq(
|
|
58
|
+
[false, "(#{value.inspect}) not within the range of acceptable values (1..65535)"]
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "and it's a service name" do
|
|
65
|
+
let(:value) { "http" }
|
|
66
|
+
|
|
67
|
+
it "must return true" do
|
|
68
|
+
expect(subject.validate(value)).to be(true)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context "and it ends with a '*' character" do
|
|
72
|
+
let(:value) { "http*" }
|
|
73
|
+
|
|
74
|
+
it "must return true" do
|
|
75
|
+
expect(subject.validate(value)).to be(true)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "and it contains uppercase letters" do
|
|
80
|
+
let(:value) { "XmlIpcRegSvc" }
|
|
81
|
+
|
|
82
|
+
it "must return true" do
|
|
83
|
+
expect(subject.validate(value)).to be(true)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "and it starts with digits" do
|
|
88
|
+
let(:value) { "1ci-smcs" }
|
|
89
|
+
|
|
90
|
+
it "must return true" do
|
|
91
|
+
expect(subject.validate(value)).to be(true)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "and it contains digits" do
|
|
96
|
+
let(:value) { "neo4j" }
|
|
97
|
+
|
|
98
|
+
it "must return true" do
|
|
99
|
+
expect(subject.validate(value)).to be(true)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "and it contains a '-' character" do
|
|
104
|
+
let(:value) { "3gpp-cbsp" }
|
|
105
|
+
|
|
106
|
+
it "must return true" do
|
|
107
|
+
expect(subject.validate(value)).to be(true)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context "but it starts with a '-' character" do
|
|
112
|
+
let(:value) { "-foo" }
|
|
113
|
+
|
|
114
|
+
it "must return [false, \"must be a port number or service name (...)\"]" do
|
|
115
|
+
expect(subject.validate(value)).to eq(
|
|
116
|
+
[false, "must be a port number or service name (#{value.inspect})"]
|
|
117
|
+
)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context "but it ends with a '-' character" do
|
|
122
|
+
let(:value) { "foo-" }
|
|
123
|
+
|
|
124
|
+
it "must return [false, \"must be a port number or service name (...)\"]" do
|
|
125
|
+
expect(subject.validate(value)).to eq(
|
|
126
|
+
[false, "must be a port number or service name (#{value.inspect})"]
|
|
127
|
+
)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "and it contains a '_' character" do
|
|
132
|
+
let(:value) { "kerberos_master" }
|
|
133
|
+
|
|
134
|
+
it "must return true" do
|
|
135
|
+
expect(subject.validate(value)).to be(true)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
context "but it starts with a '_' character" do
|
|
140
|
+
let(:value) { "_foo" }
|
|
141
|
+
|
|
142
|
+
it "must return [false, \"must be a port number or service name (...)\"]" do
|
|
143
|
+
expect(subject.validate(value)).to eq(
|
|
144
|
+
[false, "must be a port number or service name (#{value.inspect})"]
|
|
145
|
+
)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context "but it ends with a '_' character" do
|
|
150
|
+
let(:value) { "foo_" }
|
|
151
|
+
|
|
152
|
+
it "must return [false, \"must be a port number or service name (...)\"]" do
|
|
153
|
+
expect(subject.validate(value)).to eq(
|
|
154
|
+
[false, "must be a port number or service name (#{value.inspect})"]
|
|
155
|
+
)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
context "and it contain's a '/' character" do
|
|
160
|
+
let(:value) { "cl/1" }
|
|
161
|
+
|
|
162
|
+
it "must return true" do
|
|
163
|
+
expect(subject.validate(value)).to be(true)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
context "but it starts with a '/' character" do
|
|
168
|
+
let(:value) { "/foo" }
|
|
169
|
+
|
|
170
|
+
it "must return [false, \"must be a port number or service name (...)\"]" do
|
|
171
|
+
expect(subject.validate(value)).to eq(
|
|
172
|
+
[false, "must be a port number or service name (#{value.inspect})"]
|
|
173
|
+
)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
context "but it starts with a '/' character" do
|
|
178
|
+
let(:value) { "foo/" }
|
|
179
|
+
|
|
180
|
+
it "must return [false, \"must be a port number or service name (...)\"]" do
|
|
181
|
+
expect(subject.validate(value)).to eq(
|
|
182
|
+
[false, "must be a port number or service name (#{value.inspect})"]
|
|
183
|
+
)
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
describe described_class::PortRange do
|
|
192
|
+
describe "#validate" do
|
|
193
|
+
context "when given an Integer value" do
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
context "when given a String value" do
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context "when given a Range of port numbers" do
|
|
200
|
+
let(:value) { (1..1024) }
|
|
201
|
+
|
|
202
|
+
it "must return true" do
|
|
203
|
+
expect(subject.validate(value)).to be(true)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
describe "#format" do
|
|
209
|
+
context "when given a single port number" do
|
|
210
|
+
let(:value) { 443 }
|
|
211
|
+
|
|
212
|
+
it "must return the formatted port number" do
|
|
213
|
+
expect(subject.format(value)).to eq(value.to_s)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
context "when given a Range of port numbers" do
|
|
218
|
+
let(:value) { 1..1024 }
|
|
219
|
+
|
|
220
|
+
it "must return the formatted port number range (ex: 1-102)" do
|
|
221
|
+
expect(subject.format(value)).to eq("#{value.begin}-#{value.end}")
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
describe described_class::PortRangeList do
|
|
228
|
+
describe "#validate" do
|
|
229
|
+
context "when given a single port number" do
|
|
230
|
+
let(:value) { 443 }
|
|
231
|
+
|
|
232
|
+
it "must return true" do
|
|
233
|
+
expect(subject.validate(value)).to be(true)
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
context "when given a Range of port numbers" do
|
|
238
|
+
let(:value) { (1..1024) }
|
|
239
|
+
|
|
240
|
+
it "must return true" do
|
|
241
|
+
expect(subject.validate(value)).to be(true)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
context "when given an Array of port numbers" do
|
|
246
|
+
let(:value) { [80, 443] }
|
|
247
|
+
|
|
248
|
+
it "must return true" do
|
|
249
|
+
expect(subject.validate(value)).to be(true)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
context "but the Array is empty" do
|
|
253
|
+
let(:value) { [] }
|
|
254
|
+
|
|
255
|
+
it "must return [false, \"cannot be empty\"]" do
|
|
256
|
+
expect(subject.validate(value)).to eq(
|
|
257
|
+
[false, "cannot be empty"]
|
|
258
|
+
)
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
context "and the Array contains Ranges" do
|
|
263
|
+
let(:value) { [80, (1..42), 443] }
|
|
264
|
+
|
|
265
|
+
it "must return true" do
|
|
266
|
+
expect(subject.validate(value)).to be(true)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
context "when given a Hash of protocols and port numbers" do
|
|
272
|
+
let(:value) do
|
|
273
|
+
{tcp: [1,2,3,4], udp: [1,2,3,4], sctp: [1,2,3,4]}
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "must return true" do
|
|
277
|
+
expect(subject.validate(value)).to be(true)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
context "but the Hash is empty" do
|
|
281
|
+
let(:value) { {} }
|
|
282
|
+
|
|
283
|
+
it "must return [false, \"cannot be empty\"]" do
|
|
284
|
+
expect(subject.validate(value)).to eq(
|
|
285
|
+
[false, "cannot be empty"]
|
|
286
|
+
)
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
context "but one of the keys is not a known protocol" do
|
|
291
|
+
let(:protocol) { :foo }
|
|
292
|
+
let(:value) do
|
|
293
|
+
{tcp: [1,2,3,4], protocol => [1,2,3,4]}
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
it "must return [false, \"unknown protocol (...) must be :tcp, :udp, :sctp\"]" do
|
|
297
|
+
expect(subject.validate(value)).to eq(
|
|
298
|
+
[false, "unknown protocol (#{protocol.inspect}) must be :tcp, :udp, or :sctp"]
|
|
299
|
+
)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
context "but one of the Hash values is not a valid port list class" do
|
|
304
|
+
let(:bad_port_list) { Object.new }
|
|
305
|
+
let(:value) do
|
|
306
|
+
{tcp: [1,2,3,4], udp: bad_port_list, sctp: [1,2,3,4]}
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it "must return [false, \"cannot be converted into an Integer\"]" do
|
|
310
|
+
expect(subject.validate(value)).to eq(
|
|
311
|
+
[false, "element cannot be converted into an Integer (#{bad_port_list.inspect})"]
|
|
312
|
+
)
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
context "but one of the elements within the port list is not a port" do
|
|
317
|
+
let(:bad_port) { "" }
|
|
318
|
+
let(:value) do
|
|
319
|
+
{tcp: [1,2,3,4], udp: [1, bad_port, 3], sctp: [1,2,3,4]}
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it "must return [false, \"element not a valid port range (...)\"]" do
|
|
323
|
+
expect(subject.validate(value)).to eq(
|
|
324
|
+
[false, "element not a valid port range (#{bad_port.inspect})"]
|
|
325
|
+
)
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
describe "#format" do
|
|
332
|
+
context "when given a single port number" do
|
|
333
|
+
let(:value) { 443 }
|
|
334
|
+
|
|
335
|
+
it "must return the formatted port number" do
|
|
336
|
+
expect(subject.format(value)).to eq(value.to_s)
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
context "when given a Range of port numbers" do
|
|
341
|
+
let(:value) { (1..1024) }
|
|
342
|
+
|
|
343
|
+
it "must return the formatted port number range (ex: 1-102)" do
|
|
344
|
+
expect(subject.format(value)).to eq("#{value.begin}-#{value.end}")
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
context "when given an Array of port numbers" do
|
|
349
|
+
let(:value) { [80, 443] }
|
|
350
|
+
|
|
351
|
+
it "must return the formatted list of port numbers" do
|
|
352
|
+
expect(subject.format(value)).to eq(value.join(','))
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
context "and the Array contains Ranges" do
|
|
356
|
+
let(:value) { [80, (1..42), 443] }
|
|
357
|
+
|
|
358
|
+
it "must return the formatted list of port numbers and port ranges" do
|
|
359
|
+
expect(subject.format(value)).to eq("#{value[0]},#{value[1].begin}-#{value[1].end},#{value[2]}")
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
context "when given a Hash of protocols and port numbers" do
|
|
365
|
+
let(:value) do
|
|
366
|
+
{tcp: [1,2,3,4], udp: [1,2,3,4], sctp: [1,2,3,4]}
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
it "must convert the keys to capital protocol letters and format the values" do
|
|
370
|
+
expect(subject.format(value)).to eq(
|
|
371
|
+
"T:#{subject.format(value[:tcp])},U:#{subject.format(value[:udp])},S:#{subject.format(value[:sctp])}"
|
|
372
|
+
)
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
describe described_class::Time do
|
|
379
|
+
describe "#validate" do
|
|
380
|
+
context "when given nil" do
|
|
381
|
+
let(:value) { nil }
|
|
382
|
+
|
|
383
|
+
it "must return [false, \"cannot be nil\"]" do
|
|
384
|
+
expect(subject.validate(value)).to eq(
|
|
385
|
+
[false, "cannot be nil"]
|
|
386
|
+
)
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
context "when given an Integer" do
|
|
391
|
+
let(:value) { 10 }
|
|
392
|
+
|
|
393
|
+
it "must return true" do
|
|
394
|
+
expect(subject.validate(value)).to be(true)
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
context "when given a String" do
|
|
399
|
+
context "when given an empty String" do
|
|
400
|
+
let(:value) { "" }
|
|
401
|
+
|
|
402
|
+
it "must return [false, \"does not allow an empty value\"]" do
|
|
403
|
+
expect(subject.validate(value)).to eq(
|
|
404
|
+
[false, "does not allow an empty value"]
|
|
405
|
+
)
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
context "when given a number" do
|
|
410
|
+
let(:value) { "10" }
|
|
411
|
+
|
|
412
|
+
it "must return true" do
|
|
413
|
+
expect(subject.validate(value)).to be(true)
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
context "when given a number that ends with 'ms'" do
|
|
418
|
+
let(:value) { "10ms" }
|
|
419
|
+
|
|
420
|
+
it "must return true" do
|
|
421
|
+
expect(subject.validate(value)).to be(true)
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
context "when given a number that ends with 's'" do
|
|
426
|
+
let(:value) { "10s" }
|
|
427
|
+
|
|
428
|
+
it "must return true" do
|
|
429
|
+
expect(subject.validate(value)).to be(true)
|
|
430
|
+
end
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
context "when given a number that ends with 'm'" do
|
|
434
|
+
let(:value) { "10m" }
|
|
435
|
+
|
|
436
|
+
it "must return true" do
|
|
437
|
+
expect(subject.validate(value)).to be(true)
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
context "when given a number that ends with 'h'" do
|
|
442
|
+
let(:value) { "10h" }
|
|
443
|
+
|
|
444
|
+
it "must return true" do
|
|
445
|
+
expect(subject.validate(value)).to be(true)
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
context "when given a number that ends with an unrecognized unit" do
|
|
450
|
+
let(:value) { "10x" }
|
|
451
|
+
|
|
452
|
+
it "must return [false, \"must be a number and end with 'ms', 's', 'm', or 'h'\"]" do
|
|
453
|
+
expect(subject.validate(value)).to eq(
|
|
454
|
+
[false, "must be a number and end with 'ms', 's', 'm', or 'h'"]
|
|
455
|
+
)
|
|
456
|
+
end
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
describe described_class::HexString do
|
|
463
|
+
describe "#validate" do
|
|
464
|
+
context "when given nil" do
|
|
465
|
+
let(:value) { nil }
|
|
466
|
+
|
|
467
|
+
it "must return [false, \"cannot be nil\"]" do
|
|
468
|
+
expect(subject.validate(value)).to eq(
|
|
469
|
+
[false, "cannot be nil"]
|
|
470
|
+
)
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
context "when given a String" do
|
|
475
|
+
context "but it's empty" do
|
|
476
|
+
let(:value) { '' }
|
|
477
|
+
|
|
478
|
+
it "must return [false, \"does not allow an empty value\"]" do
|
|
479
|
+
expect(subject.validate(value)).to eq(
|
|
480
|
+
[false, "does not allow an empty value"]
|
|
481
|
+
)
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
context "and it's of the format 0xAABBCCDDEEFF" do
|
|
486
|
+
let(:value) { "0xAABBCCDDEEFF" }
|
|
487
|
+
|
|
488
|
+
it "must return true" do
|
|
489
|
+
expect(subject.validate(value)).to be(true)
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
context "and it's of the format AABBCCDDEEFF" do
|
|
494
|
+
let(:value) { "AABBCCDDEEFF" }
|
|
495
|
+
|
|
496
|
+
it "must return true" do
|
|
497
|
+
expect(subject.validate(value)).to be(true)
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
context "and it's of the format \\xAA\\xBB\\xCC\\xDD\\xEE\\xFF" do
|
|
502
|
+
let(:value) { "\\xAA\\xBB\\xCC\\xDD\\xEE\\xFF" }
|
|
503
|
+
|
|
504
|
+
it "must return true" do
|
|
505
|
+
expect(subject.validate(value)).to be(true)
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
context "but it contains non-hex characters" do
|
|
510
|
+
let(:value) { "abcxyz123" }
|
|
511
|
+
|
|
512
|
+
it "must return [false, \"must be of the format 0xAABBCCDDEEFF..., AABBCCDDEEFF..., or \\\\xAA\\\\xBB\\\\xCC\\\\xDD\\\\xEE\\\\xFF...\"]" do
|
|
513
|
+
expect(subject.validate(value)).to eq(
|
|
514
|
+
[false, "must be of the format 0xAABBCCDDEEFF..., AABBCCDDEEFF..., or \\xAA\\xBB\\xCC\\xDD\\xEE\\xFF..."]
|
|
515
|
+
)
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
describe described_class::ScanFlags do
|
|
523
|
+
describe "#validate" do
|
|
524
|
+
context "when given nil" do
|
|
525
|
+
let(:value) { nil }
|
|
526
|
+
|
|
527
|
+
it "must return [false, \"cannot be nil\"]" do
|
|
528
|
+
expect(subject.validate(value)).to eq(
|
|
529
|
+
[false, "cannot be nil"]
|
|
530
|
+
)
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
context "when given a String" do
|
|
535
|
+
context "but it's empty" do
|
|
536
|
+
let(:value) { '' }
|
|
537
|
+
|
|
538
|
+
it "must return [false, \"does not allow an empty value\"]" do
|
|
539
|
+
expect(subject.validate(value)).to eq(
|
|
540
|
+
[false, "does not allow an empty value"]
|
|
541
|
+
)
|
|
542
|
+
end
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
context "and it's made up of 'URG', 'ACK', 'PSH', 'RST', 'SYN', and 'FIN'" do
|
|
546
|
+
let(:value) { 'URGACKPSHRSTSYNFIN' }
|
|
547
|
+
|
|
548
|
+
it "must return true" do
|
|
549
|
+
expect(subject.validate(value)).to be(true)
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
context "but it contains other sub-strings besides 'URG', 'ACK', 'PSH', 'RST', 'SYN', and 'FIN'" do
|
|
554
|
+
let(:value) { 'URGACKPSHRSTSYNFINXXX' }
|
|
555
|
+
|
|
556
|
+
it "must return [false, \"must only contain URG, ACK, PSH, RST, SYN, or FIN\"]" do
|
|
557
|
+
expect(subject.validate(value)).to eq(
|
|
558
|
+
[false, "must only contain URG, ACK, PSH, RST, SYN, or FIN"]
|
|
559
|
+
)
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
context "and it's numeric" do
|
|
564
|
+
let(:value) { '9' }
|
|
565
|
+
|
|
566
|
+
it "must return true" do
|
|
567
|
+
expect(subject.validate(value)).to be(true)
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
context "when given an Integer" do
|
|
573
|
+
let(:value) { 9 }
|
|
574
|
+
|
|
575
|
+
it "must return true" do
|
|
576
|
+
expect(subject.validate(value)).to be(true)
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
context "when given an Array" do
|
|
581
|
+
context "but it's empty" do
|
|
582
|
+
let(:value) { [] }
|
|
583
|
+
|
|
584
|
+
it "must return [false, \"Array value cannot be empty\"]" do
|
|
585
|
+
expect(subject.validate(value)).to eq(
|
|
586
|
+
[false, "Array value cannot be empty"]
|
|
587
|
+
)
|
|
588
|
+
end
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
context "and it contains :urg, :ack, :psh, :rst, :syn, or :fin" do
|
|
592
|
+
let(:value) { [:urg, :ack, :psh, :rst, :syn, :fin] }
|
|
593
|
+
|
|
594
|
+
it "must return true" do
|
|
595
|
+
expect(subject.validate(value)).to be(true)
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
context "but it contains other values besides :urg, :ack, :psh, :rst, :syn, and :fin" do
|
|
600
|
+
let(:other) { :foo }
|
|
601
|
+
let(:value) { [:urg, :ack, :psh, :rst, :syn, :fin, other] }
|
|
602
|
+
|
|
603
|
+
it "must return true" do
|
|
604
|
+
expect(subject.validate(value)).to eq(
|
|
605
|
+
[false, "Array must only contain the values :urg, :ack, :psh, :rst, :syn, or :fin"]
|
|
606
|
+
)
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
context "when given a Hash" do
|
|
612
|
+
context "but it's empty" do
|
|
613
|
+
let(:value) { {} }
|
|
614
|
+
|
|
615
|
+
it "must return [false, \"Hash value cannot be empty\"]" do
|
|
616
|
+
expect(subject.validate(value)).to eq(
|
|
617
|
+
[false, "Hash value cannot be empty"]
|
|
618
|
+
)
|
|
619
|
+
end
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
context "and it's keys contain :urg, :ack, :psh, :rst, :syn, or :fin" do
|
|
623
|
+
context "and it's values are all Boolean" do
|
|
624
|
+
let(:value) do
|
|
625
|
+
{
|
|
626
|
+
urg: true,
|
|
627
|
+
ack: true,
|
|
628
|
+
psh: false,
|
|
629
|
+
rst: nil,
|
|
630
|
+
syn: true,
|
|
631
|
+
fin: true
|
|
632
|
+
}
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
it "must return true" do
|
|
636
|
+
expect(subject.validate(value)).to be(true)
|
|
637
|
+
end
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
context "but one of it's values is not a Boolean value" do
|
|
641
|
+
let(:value) do
|
|
642
|
+
{
|
|
643
|
+
urg: true,
|
|
644
|
+
ack: true,
|
|
645
|
+
psh: false,
|
|
646
|
+
rst: nil,
|
|
647
|
+
syn: true,
|
|
648
|
+
fin: "foo"
|
|
649
|
+
}
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
it "must return [false, \"must only contain the Boolean values\"]" do
|
|
653
|
+
expect(subject.validate(value)).to eq(
|
|
654
|
+
[false, "Hash must only contain the values true, false, or nil"]
|
|
655
|
+
)
|
|
656
|
+
end
|
|
657
|
+
end
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
context "but it's keys contains other values besides :urg, :ack, :psh, :rst, :syn, and :fin" do
|
|
661
|
+
let(:other) { :foo }
|
|
662
|
+
let(:value) do
|
|
663
|
+
{
|
|
664
|
+
urg: true,
|
|
665
|
+
ack: true,
|
|
666
|
+
psh: true,
|
|
667
|
+
rst: true,
|
|
668
|
+
syn: true,
|
|
669
|
+
fin: true,
|
|
670
|
+
other => true
|
|
671
|
+
}
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
it "must return [false, \"must only contain the keys :urg, :ack, :psh, :rst, :syn, or :fin\"]" do
|
|
675
|
+
expect(subject.validate(value)).to eq(
|
|
676
|
+
[false, "Hash must only contain the keys :urg, :ack, :psh, :rst, :syn, or :fin"]
|
|
677
|
+
)
|
|
678
|
+
end
|
|
679
|
+
end
|
|
680
|
+
end
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
describe "#format" do
|
|
684
|
+
context "when given a String" do
|
|
685
|
+
let(:value) { 'PSHFIN' }
|
|
686
|
+
|
|
687
|
+
it "must return the String" do
|
|
688
|
+
expect(subject.format(value)).to eq(value)
|
|
689
|
+
end
|
|
690
|
+
end
|
|
691
|
+
|
|
692
|
+
context "when given an Integer" do
|
|
693
|
+
let(:value) { 9 }
|
|
694
|
+
|
|
695
|
+
it "must return the String version of the Integer" do
|
|
696
|
+
expect(subject.format(value)).to eq(value.to_s)
|
|
697
|
+
end
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
context "when given an Array" do
|
|
701
|
+
let(:value) { [:urg, :ack, :psh, :rst, :syn, :fin] }
|
|
702
|
+
|
|
703
|
+
it "must map each Symbol to their flag names value and join them together" do
|
|
704
|
+
expect(subject.format(value)).to eq("URGACKPSHRSTSYNFIN")
|
|
705
|
+
end
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
context "when given a Hash" do
|
|
709
|
+
let(:value) do
|
|
710
|
+
{
|
|
711
|
+
urg: true,
|
|
712
|
+
ack: true,
|
|
713
|
+
psh: false,
|
|
714
|
+
rst: nil,
|
|
715
|
+
syn: true,
|
|
716
|
+
fin: true
|
|
717
|
+
}
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
it "must map the keys with true values to their flag names and join them together" do
|
|
721
|
+
expect(subject.format(value)).to eq("URGACKSYNFIN")
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
end
|
|
725
|
+
end
|
|
726
|
+
end
|