metasploit_data_models 0.18.1 → 0.19.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 +8 -8
- data/app/models/mdm/host.rb +7 -0
- data/app/models/mdm/service.rb +30 -1
- data/app/models/mdm/tag.rb +10 -0
- data/app/models/metasploit_data_models/ip_address/v4/cidr.rb +14 -0
- data/app/models/metasploit_data_models/ip_address/v4/nmap.rb +14 -0
- data/app/models/metasploit_data_models/ip_address/v4/range.rb +12 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list.rb +126 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range.rb +12 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/single.rb +123 -0
- data/app/models/metasploit_data_models/ip_address/v4/segmented.rb +200 -0
- data/app/models/metasploit_data_models/ip_address/v4/single.rb +53 -0
- data/app/models/metasploit_data_models/search/operation/ip_address.rb +60 -0
- data/app/models/metasploit_data_models/search/operator/ip_address.rb +33 -0
- data/app/models/metasploit_data_models/search/visitor/attribute.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/includes.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/joins.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/where.rb +51 -0
- data/config/locales/en.yml +35 -4
- data/lib/metasploit_data_models/ip_address.rb +5 -0
- data/lib/metasploit_data_models/ip_address/cidr.rb +174 -0
- data/lib/metasploit_data_models/ip_address/range.rb +181 -0
- data/lib/metasploit_data_models/match/child.rb +48 -0
- data/lib/metasploit_data_models/match/parent.rb +103 -0
- data/lib/metasploit_data_models/version.rb +4 -4
- data/metasploit_data_models.gemspec +2 -1
- data/spec/app/models/mdm/cred_spec.rb +164 -31
- data/spec/app/models/mdm/service_spec.rb +33 -44
- data/spec/app/models/metasploit_data_models/ip_address/v4/cidr_spec.rb +121 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/nmap_spec.rb +151 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/range_spec.rb +300 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list_spec.rb +278 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range_spec.rb +304 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/segmented_spec.rb +29 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/single_spec.rb +315 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/single_spec.rb +183 -0
- data/spec/app/models/metasploit_data_models/search/operation/ip_address_spec.rb +182 -0
- data/spec/app/models/metasploit_data_models/search/operator/ip_address_spec.rb +19 -0
- data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +229 -36
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/db/structure.sql +3011 -0
- data/spec/factories/mdm/services.rb +3 -1
- data/spec/lib/metasploit_data_models/ip_address/cidr_spec.rb +350 -0
- data/spec/lib/metasploit_data_models/ip_address/range_spec.rb +77 -0
- data/spec/lib/metasploit_data_models/match/child_spec.rb +61 -0
- data/spec/lib/metasploit_data_models/match/parent_spec.rb +155 -0
- data/spec/support/matchers/match_regex_exactly.rb +28 -0
- data/spec/support/shared/contexts/rex/text.rb +15 -0
- data/spec/support/shared/examples/metasploit_data_models/search/operation/ipaddress/match.rb +109 -0
- metadata +58 -9
- data/spec/dummy/db/schema.rb +0 -609
@@ -0,0 +1,278 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::Segment::Nmap::List do
|
4
|
+
subject(:nmap) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
context 'CONSTANTS' do
|
11
|
+
context 'MATCH_REGEXP' do
|
12
|
+
subject(:match_regexp) {
|
13
|
+
described_class::MATCH_REGEXP
|
14
|
+
}
|
15
|
+
|
16
|
+
it 'matches comma separated list of segment numbers and range' do
|
17
|
+
expect(match_regexp).to match('1,2-3,4-5,6,7-8,9')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'does not match an Nmap IP address' do
|
21
|
+
segment = '1,2-3,4-5,6,7-8,9'
|
22
|
+
expect(match_regexp).not_to match(([segment]*4).join('.'))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'RANGE_OR_NUMBER_REGEXP' do
|
27
|
+
subject(:range_or_number_regexp) {
|
28
|
+
described_class::RANGE_OR_NUMBER_REGEXP
|
29
|
+
}
|
30
|
+
|
31
|
+
it 'matches a number' do
|
32
|
+
expect(range_or_number_regexp).to match_string_exactly('0')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'matches a range' do
|
36
|
+
expect(range_or_number_regexp).to match_string_exactly('0-255')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'REGEXP' do
|
41
|
+
subject(:regexp) {
|
42
|
+
described_class::REGEXP
|
43
|
+
}
|
44
|
+
|
45
|
+
it 'matches a number' do
|
46
|
+
expect(regexp).to match_string_exactly('0')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'matches a range' do
|
50
|
+
expect(regexp).to match_string_exactly('0-255')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'matches comma separated list of numbers' do
|
54
|
+
expect(regexp).to match_string_exactly('0,1,2')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'matches comma separated list of ranges' do
|
58
|
+
expect(regexp).to match_string_exactly('1-2,3-4,5-6')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'matches commad separated list of numbers and ranges' do
|
62
|
+
expect(regexp).to match_string_exactly('1,2-3,4-5,6,7-8,9')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'SEPARATOR' do
|
67
|
+
subject(:separator) {
|
68
|
+
described_class::SEPARATOR
|
69
|
+
}
|
70
|
+
|
71
|
+
it { should == ',' }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'validation' do
|
76
|
+
before(:each) do
|
77
|
+
nmap.valid?
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'errors on #value' do
|
81
|
+
subject(:value_errors) {
|
82
|
+
nmap.errors[:value]
|
83
|
+
}
|
84
|
+
|
85
|
+
context 'with nil' do
|
86
|
+
let(:blank_error) {
|
87
|
+
I18n.translate!('errors.messages.blank')
|
88
|
+
}
|
89
|
+
|
90
|
+
let(:formatted_value) {
|
91
|
+
nil
|
92
|
+
}
|
93
|
+
|
94
|
+
it { should include blank_error }
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'with matching String' do
|
98
|
+
context 'with valid elements' do
|
99
|
+
let(:formatted_value) {
|
100
|
+
'1,2-3'
|
101
|
+
}
|
102
|
+
|
103
|
+
it { should be_empty }
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'with invalid MetasploitDataModels::IPAddress::V4::Nmap::Range' do
|
107
|
+
let(:error) {
|
108
|
+
I18n.translate!(
|
109
|
+
'metasploit.model.errors.models.metasploit_data_models/ip_address/v4/segment/nmap/list.attributes.value.element',
|
110
|
+
element: '255-0',
|
111
|
+
index: 1
|
112
|
+
)
|
113
|
+
}
|
114
|
+
|
115
|
+
let(:formatted_value) {
|
116
|
+
'1,255-0'
|
117
|
+
}
|
118
|
+
|
119
|
+
it 'says index of element that as invalid with the value' do
|
120
|
+
expect(value_errors).to include(error)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'without matching String' do
|
126
|
+
let(:array_error) {
|
127
|
+
I18n.translate!('metasploit.model.errors.models.metasploit_data_models/ip_address/v4/segment/nmap/list.attributes.value.array')
|
128
|
+
}
|
129
|
+
|
130
|
+
let(:formatted_value) {
|
131
|
+
'non_matching_string'
|
132
|
+
}
|
133
|
+
|
134
|
+
it { should include array_error }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context '#to_s' do
|
140
|
+
subject(:to_s) do
|
141
|
+
nmap.to_s
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'with matching formatted value' do
|
145
|
+
let(:formatted_value) {
|
146
|
+
'1,2-3'
|
147
|
+
}
|
148
|
+
|
149
|
+
it 'returns a string equal to the original formatted value' do
|
150
|
+
expect(to_s).to eq(formatted_value)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'without matching formatted value' do
|
155
|
+
let(:formatted_value) {
|
156
|
+
Set.new([1,2])
|
157
|
+
}
|
158
|
+
|
159
|
+
it 'returned the formatted value as a string' do
|
160
|
+
expect(to_s).to eq(formatted_value.to_s)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context '#value' do
|
166
|
+
subject(:value) {
|
167
|
+
nmap.value
|
168
|
+
}
|
169
|
+
|
170
|
+
context 'with segment number' do
|
171
|
+
let(:formatted_value) {
|
172
|
+
number.to_s
|
173
|
+
}
|
174
|
+
|
175
|
+
let(:number) {
|
176
|
+
255
|
177
|
+
}
|
178
|
+
|
179
|
+
it 'has correct number of elements' do
|
180
|
+
expect(value.length).to eq(1)
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'only element' do
|
184
|
+
subject(:element) {
|
185
|
+
value.first
|
186
|
+
}
|
187
|
+
|
188
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Segment::Single }
|
189
|
+
|
190
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Single#value' do
|
191
|
+
it 'is value from formatted_value' do
|
192
|
+
expect(element.value).to eq(number)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'with segment range' do
|
199
|
+
let(:begin_number) {
|
200
|
+
0
|
201
|
+
}
|
202
|
+
|
203
|
+
let(:end_number) {
|
204
|
+
255
|
205
|
+
}
|
206
|
+
|
207
|
+
let(:formatted_value) {
|
208
|
+
"#{begin_number}-#{end_number}"
|
209
|
+
}
|
210
|
+
|
211
|
+
it 'has correct number of elements' do
|
212
|
+
expect(value.length).to eq(1)
|
213
|
+
end
|
214
|
+
|
215
|
+
context 'only element' do
|
216
|
+
subject(:element) {
|
217
|
+
value.first
|
218
|
+
}
|
219
|
+
|
220
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range }
|
221
|
+
|
222
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range#value' do
|
223
|
+
subject(:element_value) {
|
224
|
+
element.value
|
225
|
+
}
|
226
|
+
|
227
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range#begin' do
|
228
|
+
subject(:range_begin) {
|
229
|
+
element_value.begin
|
230
|
+
}
|
231
|
+
|
232
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Segment::Single }
|
233
|
+
|
234
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Single#value' do
|
235
|
+
it 'is beginning of formatted value' do
|
236
|
+
expect(range_begin.value).to eq(begin_number)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range#end' do
|
242
|
+
subject(:range_end) {
|
243
|
+
element_value.end
|
244
|
+
}
|
245
|
+
|
246
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Segment::Single }
|
247
|
+
|
248
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Single#value' do
|
249
|
+
it 'is beginning of formatted value' do
|
250
|
+
expect(range_end.value).to eq(end_number)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context 'with comma separated list of segment numbers and ranges' do
|
259
|
+
let(:formatted_value) {
|
260
|
+
'1,2-3,4-5,6,7'
|
261
|
+
}
|
262
|
+
|
263
|
+
it 'has correct number elements' do
|
264
|
+
expect(value.length).to eq(5)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context 'with additional data' do
|
269
|
+
let(:formatted_value) {
|
270
|
+
'additional_data1,2-3'
|
271
|
+
}
|
272
|
+
|
273
|
+
it 'is original formatted value' do
|
274
|
+
expect(value).to eq(formatted_value)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
@@ -0,0 +1,304 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range do
|
4
|
+
subject(:range) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
#
|
11
|
+
# lets
|
12
|
+
#
|
13
|
+
|
14
|
+
let(:formatted_value) {
|
15
|
+
nil
|
16
|
+
}
|
17
|
+
|
18
|
+
context 'validations' do
|
19
|
+
#
|
20
|
+
# lets
|
21
|
+
#
|
22
|
+
|
23
|
+
let(:presence_error) {
|
24
|
+
I18n.translate!('errors.messages.blank')
|
25
|
+
}
|
26
|
+
|
27
|
+
let(:invalid_error) {
|
28
|
+
I18n.translate!('errors.messages.invalid')
|
29
|
+
}
|
30
|
+
|
31
|
+
#
|
32
|
+
# Callbacks
|
33
|
+
#
|
34
|
+
|
35
|
+
before(:each) do
|
36
|
+
range.valid?
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'errors on #begin' do
|
40
|
+
subject(:begin_errors) {
|
41
|
+
range.errors[:begin]
|
42
|
+
}
|
43
|
+
|
44
|
+
context '#begin' do
|
45
|
+
context 'with nil' do
|
46
|
+
let(:formatted_value) {
|
47
|
+
nil
|
48
|
+
}
|
49
|
+
|
50
|
+
it { should include presence_error }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with MetasploitDataModels::IPAddress::V4::Segment' do
|
54
|
+
context 'with valid' do
|
55
|
+
let(:formatted_value) {
|
56
|
+
'1-256'
|
57
|
+
}
|
58
|
+
|
59
|
+
it { should_not include invalid_error }
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'without valid' do
|
63
|
+
let(:formatted_value) {
|
64
|
+
'256-257'
|
65
|
+
}
|
66
|
+
|
67
|
+
it { should include invalid_error }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'errors on #end' do
|
74
|
+
subject(:end_errors) {
|
75
|
+
range.errors[:end]
|
76
|
+
}
|
77
|
+
|
78
|
+
context '#end' do
|
79
|
+
context 'with nil' do
|
80
|
+
let(:formatted_value) {
|
81
|
+
nil
|
82
|
+
}
|
83
|
+
|
84
|
+
it { should include presence_error }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'with MetasploitDataModels::IPAddress::V4::Segment' do
|
88
|
+
context 'with valid' do
|
89
|
+
let(:formatted_value) {
|
90
|
+
'256-1'
|
91
|
+
}
|
92
|
+
|
93
|
+
it { should_not include invalid_error }
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'without valid' do
|
97
|
+
let(:formatted_value) {
|
98
|
+
'257-256'
|
99
|
+
}
|
100
|
+
|
101
|
+
it { should include invalid_error }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'errors on #value' do
|
108
|
+
subject(:value_errors) {
|
109
|
+
range.errors[:value]
|
110
|
+
}
|
111
|
+
|
112
|
+
let(:error) {
|
113
|
+
I18n.translate!(
|
114
|
+
'metasploit.model.errors.models.metasploit_data_models/ip_address/v4/segment/nmap/range.attributes.value.order',
|
115
|
+
begin: range.begin,
|
116
|
+
end: range.end
|
117
|
+
)
|
118
|
+
}
|
119
|
+
|
120
|
+
context 'with nil' do
|
121
|
+
let(:formatted_value) {
|
122
|
+
nil
|
123
|
+
}
|
124
|
+
|
125
|
+
it { should_not include error }
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'with incomparables' do
|
129
|
+
let(:formatted_value) {
|
130
|
+
'a-1'
|
131
|
+
}
|
132
|
+
|
133
|
+
it { should_not include error }
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with numbers' do
|
137
|
+
context 'in order' do
|
138
|
+
let(:formatted_value) {
|
139
|
+
'1-2'
|
140
|
+
}
|
141
|
+
|
142
|
+
it { should_not include error }
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'out of order' do
|
146
|
+
let(:formatted_value) {
|
147
|
+
'2-1'
|
148
|
+
}
|
149
|
+
|
150
|
+
it { should include error }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'match_regexp' do
|
157
|
+
subject(:match_regexp) do
|
158
|
+
described_class::match_regexp
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'matches range exactly' do
|
162
|
+
expect(match_regexp).to match_string_exactly('0-255')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'regexp' do
|
167
|
+
subject(:regexp) {
|
168
|
+
described_class::regexp
|
169
|
+
}
|
170
|
+
|
171
|
+
it 'does not match a single segment number' do
|
172
|
+
expect(regexp).not_to match('255')
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'does not match separator by itself' do
|
176
|
+
expect(regexp).not_to match('-')
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'does not match range with only one extreme' do
|
180
|
+
expect(regexp).not_to match('0-')
|
181
|
+
expect(regexp).not_to match('-255')
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'matches range' do
|
185
|
+
expect(regexp).to match_string_exactly('0-255')
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context '#to_s' do
|
190
|
+
subject(:to_s) {
|
191
|
+
range.to_s
|
192
|
+
}
|
193
|
+
|
194
|
+
context 'with Range' do
|
195
|
+
let(:formatted_value) {
|
196
|
+
'1-2'
|
197
|
+
}
|
198
|
+
|
199
|
+
it 'equals the original formatted value' do
|
200
|
+
expect(to_s).to eq(formatted_value)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'without Range' do
|
205
|
+
let(:formatted_value) {
|
206
|
+
'1..2'
|
207
|
+
}
|
208
|
+
|
209
|
+
it { should == '-' }
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context '#value' do
|
214
|
+
subject(:value) {
|
215
|
+
range.value
|
216
|
+
}
|
217
|
+
|
218
|
+
context 'with -' do
|
219
|
+
context 'with extremes' do
|
220
|
+
let(:formatted_value) {
|
221
|
+
'1-2'
|
222
|
+
}
|
223
|
+
|
224
|
+
it { should be_a Range }
|
225
|
+
|
226
|
+
context 'Range#begin' do
|
227
|
+
subject(:range_begin) {
|
228
|
+
value.begin
|
229
|
+
}
|
230
|
+
|
231
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Segment::Single }
|
232
|
+
|
233
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Single#value' do
|
234
|
+
it "is value before '-'" do
|
235
|
+
expect(range_begin.value).to eq(1)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'Range#end' do
|
241
|
+
subject(:range_end) {
|
242
|
+
value.end
|
243
|
+
}
|
244
|
+
|
245
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Segment::Single }
|
246
|
+
|
247
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Single#value' do
|
248
|
+
it "is value after '-'" do
|
249
|
+
expect(range_end.value).to eq(2)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
context 'without extremes' do
|
256
|
+
let(:formatted_value) {
|
257
|
+
'-'
|
258
|
+
}
|
259
|
+
|
260
|
+
it { should be_a Range }
|
261
|
+
|
262
|
+
context 'Range#begin' do
|
263
|
+
subject(:range_begin) {
|
264
|
+
value.begin
|
265
|
+
}
|
266
|
+
|
267
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Segment::Single }
|
268
|
+
|
269
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Single#value' do
|
270
|
+
subject(:begin_value) {
|
271
|
+
range_begin.value
|
272
|
+
}
|
273
|
+
|
274
|
+
it { should == '' }
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context 'Range#end' do
|
279
|
+
subject(:range_end) {
|
280
|
+
value.end
|
281
|
+
}
|
282
|
+
|
283
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Segment::Single }
|
284
|
+
|
285
|
+
context 'MetasploitDataModels::IPAddress::V4::Segment::Single#value' do
|
286
|
+
subject(:end_value) {
|
287
|
+
range_end.value
|
288
|
+
}
|
289
|
+
|
290
|
+
it { should == '' }
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context 'without -' do
|
297
|
+
let(:formatted_value) do
|
298
|
+
'1'
|
299
|
+
end
|
300
|
+
|
301
|
+
it { should_not be_a Range }
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|