Skip to content

Commit 890236d

Browse files
committed
Added IPRange::Range#=== (closes #491).
1 parent 1d63860 commit 890236d

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

.rubocop.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ Style/CaseEquality:
122122
- 'spec/network/ip_range_spec.rb'
123123
- 'spec/network/ip_range/cidr_spec.rb'
124124
- 'spec/network/ip_range/glob_spec.rb'
125+
- 'spec/network/ip_range/range_spec.rb'
125126

126127
Style/ConditionalAssignment:
127128
Exclude:

lib/ronin/support/network/ip_range/range.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,25 @@ def ==(other)
207207
self.end == other.end
208208
end
209209

210+
#
211+
# Determines if the given IP range is a sub-set of the IP range.
212+
#
213+
# @param [IPRange::Range, CIDR, Glob, Enumerable<String>] other
214+
# The other IP range.
215+
#
216+
# @return [Boolean]
217+
#
218+
# @since 1.1.0
219+
#
220+
def ===(other)
221+
case other
222+
when IPRange::Range
223+
self.begin <= other.begin && self.end >= other.end
224+
else
225+
other.all? { |ip| include?(ip) }
226+
end
227+
end
228+
210229
#
211230
# Calculates the size of the IP range.
212231
#

spec/network/ip_range/range_spec.rb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,62 @@
301301
end
302302
end
303303

304+
describe "#===" do
305+
let(:cidr) { '10.1.1.1/24' }
306+
307+
context "when given Ronin::Support::Network::IPRange::Range" do
308+
context "and the other IP range is equal to the IP range" do
309+
let(:other) { described_class.new(first,last) }
310+
311+
it "must return true" do
312+
expect(subject === other).to be(true)
313+
end
314+
end
315+
316+
context "and the other IP range is a subset within the IP range" do
317+
let(:other_first) { '127.0.0.128' }
318+
let(:other_last) { '127.0.1.0' }
319+
let(:other) { described_class.new(other_first,other_last) }
320+
321+
it "must return true" do
322+
expect(subject === other).to be(true)
323+
end
324+
end
325+
326+
context "and the other IP range does not overlap with the IP range" do
327+
let(:other_first) { '1.0.0.0' }
328+
let(:other_last) { '1.0.0.1' }
329+
let(:other) { described_class.new(other_first,other_last) }
330+
331+
it "must return false" do
332+
expect(subject === other).to be(false)
333+
end
334+
end
335+
end
336+
337+
context "when given an Enumerable object" do
338+
let(:other) do
339+
(128..255).map { |i| "127.0.0.%d" % i }
340+
end
341+
342+
context "and when every IP in the Enumerable object is included in the IP range" do
343+
it "must return true" do
344+
expect(subject === other).to be(true)
345+
end
346+
end
347+
348+
context "but one of the IPs in the Enumerable object is not included in the IP range" do
349+
let(:other) do
350+
super() + ['127.0.1.255']
351+
end
352+
353+
it "must return false" do
354+
expect(subject === other).to be(false)
355+
end
356+
end
357+
end
358+
end
359+
304360
describe "#size" do
305361
it "must return the number of IPs in the IP range" do
306362
expect(subject.size).to eq(256)

0 commit comments

Comments
 (0)