ipaddress 0.5.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.
@@ -0,0 +1,200 @@
1
+ module IPAddress
2
+
3
+ #
4
+ # =NAME
5
+ #
6
+ # IPAddress::Prefix
7
+ #
8
+ # =SYNOPSIS
9
+ #
10
+ # Parent class for Prefix32 and Prefix128
11
+ #
12
+ # =DESCRIPTION
13
+ #
14
+ # IPAddresS::Prefix is the parent class for IPAddress::Prefix32
15
+ # and IPAddress::Prefix128, defining some modules in common for
16
+ # both the subclasses.
17
+ #
18
+ # IPAddress::Prefix shouldn't be accesses directly, unless
19
+ # for particular needs.
20
+ #
21
+ class Prefix
22
+
23
+ include Comparable
24
+
25
+ attr_reader :prefix
26
+
27
+ def initialize(num)
28
+ @prefix = num.to_i
29
+ end
30
+
31
+ def to_s
32
+ "#@prefix"
33
+ end
34
+ alias_method :inspect, :to_s
35
+
36
+ def to_i
37
+ @prefix
38
+ end
39
+
40
+ def <=>(oth)
41
+ @prefix <=> oth.to_i
42
+ end
43
+
44
+ end # class Prefix
45
+
46
+
47
+ class Prefix32 < Prefix
48
+
49
+ #
50
+ # Creates a new prefix object for 32 bits IPv4 addresses
51
+ #
52
+ # prefix = IPAddress::Prefix32.new 24
53
+ # #=> 24
54
+ #
55
+ def initialize(num)
56
+ unless (1..32).include? num
57
+ raise ArgumentError, "Prefix must be in range 1..128, got: #{num}"
58
+ end
59
+ super(num)
60
+ end
61
+
62
+ #
63
+ # Transforms the prefix into a string of bits
64
+ # representing the netmask
65
+ #
66
+ # prefix = IPAddress::Prefix32.new 24
67
+ #
68
+ # prefix.bits
69
+ # #=> "11111111111111111111111100000000"
70
+ #
71
+ def bits
72
+ "1" * @prefix + "0" * (32 - @prefix)
73
+ end
74
+
75
+ #
76
+ # Gives the prefix in IPv4 dotted decimal format,
77
+ # i.e. the canonical netmask we're all used to
78
+ #
79
+ # prefix = IPAddress::Prefix32.new 24
80
+ #
81
+ # prefix.to_ip
82
+ # #=> "255.255.255.0"
83
+ #
84
+ def to_ip
85
+ [bits].pack("B*").unpack("CCCC").join(".")
86
+ end
87
+
88
+ #
89
+ # An array of octets of the IPv4 dotted decimal
90
+ # format
91
+ #
92
+ # prefix = IPAddress::Prefix32.new 24
93
+ #
94
+ # prefix.octets
95
+ # #=> [255, 255, 255, 0]
96
+ #
97
+ def octets
98
+ to_ip.split(".").map{|i| i.to_i}
99
+ end
100
+
101
+ #
102
+ # Unsigned 32 bits decimal number representing
103
+ # the prefix
104
+ #
105
+ # prefix = IPAddress::Prefix32.new 24
106
+ #
107
+ # prefix.to_u32
108
+ # #=> 4294967040
109
+ #
110
+ def to_u32
111
+ [bits].pack("B*").unpack("N").first
112
+ end
113
+
114
+ #
115
+ # Shortcut for the octecs in the dotted decimal
116
+ # representation
117
+ #
118
+ # prefix = IPAddress::Prefix32.new 24
119
+ #
120
+ # prefix[2]
121
+ # #=> 255
122
+ #
123
+ def [](index)
124
+ octets[index]
125
+ end
126
+
127
+ #
128
+ # The hostmask is the contrary of the subnet mask,
129
+ # as it shows the bits that can change within the
130
+ # hosts
131
+ #
132
+ # prefix = IPAddress::Prefix32.new 24
133
+ #
134
+ # prefix.hostmask
135
+ # #=> "0.0.0.255"
136
+ #
137
+ def hostmask
138
+ [~to_u32].pack("N").unpack("CCCC").join(".")
139
+ end
140
+
141
+ #
142
+ # Creates a new prefix by parsing a netmask in
143
+ # dotted decimal form
144
+ #
145
+ # prefix = IPAddress::Prefix32::parse_netmask "255.255.255.0"
146
+ # #=> 24
147
+ #
148
+ def self.parse_netmask(netmask)
149
+ octets = netmask.split(".").map{|i| i.to_i}
150
+ num = octets.pack("C"*octets.size).unpack("B*").first.count "1"
151
+ return IPAddress::Prefix.new(num)
152
+ end
153
+
154
+ end # class Prefix32 < Prefix
155
+
156
+ class Prefix128 < Prefix
157
+
158
+ #
159
+ # Creates a new prefix object for 128 bits IPv6 addresses
160
+ #
161
+ # prefix = IPAddress::Prefix128.new 64
162
+ # #=> 64
163
+ #
164
+ def initialize(num=128)
165
+ unless (1..128).include? num.to_i
166
+ raise ArgumentError, "Prefix must be in range 1..128, got: #{num}"
167
+ end
168
+ super(num.to_i)
169
+ end
170
+
171
+ #
172
+ # Transforms the prefix into a string of bits
173
+ # representing the netmask
174
+ #
175
+ # prefix = IPAddress::Prefix128.new 64
176
+ #
177
+ # prefix.bits
178
+ # #=> "1111111111111111111111111111111111111111111111111111111111111111"
179
+ # "0000000000000000000000000000000000000000000000000000000000000000"
180
+ #
181
+ def bits
182
+ "1" * @prefix + "0" * (128 - @prefix)
183
+ end
184
+
185
+ #
186
+ # Unsigned 128 bits decimal number representing
187
+ # the prefix
188
+ #
189
+ # prefix = IPAddress::Prefix128.new 64
190
+ #
191
+ # prefix.to_u128
192
+ # #=> 340282366920938463444927863358058659840
193
+ #
194
+ def to_u128
195
+ eval "0b#{bits}.to_i"
196
+ end
197
+
198
+ end # class Prefix123 < Prefix
199
+
200
+ end # module IPAddress
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ class ExtensionsTest < Test::Unit::TestCase
4
+
5
+ def test_method_power_of_2?
6
+ assert_equal true, 16.power_of_2?
7
+ assert_equal false, 20.power_of_2?
8
+ end
9
+
10
+ def test_method_closest_power_of_2
11
+ assert_equal 8, 6.closest_power_of_2
12
+ assert_equal 16, 13.closest_power_of_2
13
+ assert_equal 32, 24.closest_power_of_2
14
+ end
15
+
16
+ end
17
+
18
+
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+
3
+ class IpaddressTest < Test::Unit::TestCase
4
+
5
+ must "be valid ip" do
6
+ assert_equal true, IPAddress::valid?("10.0.0.1")
7
+ assert_equal true, IPAddress::valid?("10.0.0.0")
8
+ assert_equal true, IPAddress::valid?("2002::1")
9
+ assert_equal true, IPAddress::valid?("dead:beef:cafe:babe::f0ad")
10
+ end
11
+
12
+ must "be valid netmask" do
13
+ assert_equal true, IPAddress::valid_ipv4_netmask?("255.255.255.0")
14
+ end
15
+
16
+ must "be invalid netmask" do
17
+ assert_equal false, IPAddress::valid_ipv4_netmask?("10.0.0.1")
18
+ end
19
+
20
+ must "be invalid" do
21
+ assert_equal false, IPAddress::valid?("10.0.0.256")
22
+ assert_equal false, IPAddress::valid?("10.0.0.0.0")
23
+ assert_equal false, IPAddress::valid?("10.0.0")
24
+ assert_equal false, IPAddress::valid?("10.0")
25
+ assert_equal false, IPAddress::valid?("2002:::1")
26
+ end
27
+
28
+ end
@@ -0,0 +1,392 @@
1
+ require 'test_helper'
2
+
3
+ class IPv4Test < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @klass = IPAddress::IPv4
7
+
8
+ @valid_ipv4 = {
9
+ "10.0.0.0" => ["10.0.0.0", 8],
10
+ "10.0.0.1" => ["10.0.0.1", 8],
11
+ "10.0.0.1/24" => ["10.0.0.1", 24],
12
+ "10.0.0.1/255.255.255.0" => ["10.0.0.1", 24]}
13
+
14
+ @invalid_ipv4 = ["10.0.0.256",
15
+ "10.0.0.0.0",
16
+ "10.0.0",
17
+ "10.0"]
18
+
19
+ @valid_ipv4_range = ["10.0.0.1-254",
20
+ "10.0.1-254.0",
21
+ "10.1-254.0.0"]
22
+
23
+ @netmask_values = {
24
+ "10.0.0.0/8" => "255.0.0.0",
25
+ "172.16.0.0/16" => "255.255.0.0",
26
+ "192.168.0.0/24" => "255.255.255.0",
27
+ "192.168.100.4/30" => "255.255.255.252"}
28
+
29
+ @decimal_values ={
30
+ "10.0.0.0/8" => 167772160,
31
+ "172.16.0.0/16" => 2886729728,
32
+ "192.168.0.0/24" => 3232235520,
33
+ "192.168.100.4/30" => 3232261124}
34
+
35
+ @ip = @klass.new("172.16.10.1/24")
36
+ @network = @klass.new("172.16.10.0/24")
37
+
38
+ @broadcast = {
39
+ "10.0.0.0/8" => "10.255.255.255/8",
40
+ "172.16.0.0/16" => "172.16.255.255/16",
41
+ "192.168.0.0/24" => "192.168.0.255/24",
42
+ "192.168.100.4/30" => "192.168.100.7/30"}
43
+
44
+ @networks = {
45
+ "10.5.4.3/8" => "10.0.0.0/8",
46
+ "172.16.5.4/16" => "172.16.0.0/16",
47
+ "192.168.4.3/24" => "192.168.4.0/24",
48
+ "192.168.100.5/30" => "192.168.100.4/30"}
49
+
50
+ @class_a = @klass.new("10.0.0.1/8")
51
+ @class_b = @klass.new("172.16.0.1/16")
52
+ @class_c = @klass.new("192.168.0.1/24")
53
+
54
+ end
55
+
56
+ def test_initialize
57
+ @valid_ipv4.keys.each do |i|
58
+ ip = @klass.new(i)
59
+ assert_instance_of @klass, ip
60
+ end
61
+ assert_instance_of IPAddress::Prefix32, @ip.prefix
62
+ assert_raise (ArgumentError) do
63
+ @klass.new
64
+ end
65
+ assert_nothing_raised do
66
+ @klass.new "10.0.0.0/8"
67
+ end
68
+ end
69
+
70
+ def test_initialize_format_error
71
+ @invalid_ipv4.each do |i|
72
+ assert_raise(ArgumentError) {@klass.new(i)}
73
+ end
74
+ assert_raise (ArgumentError) {@klass.new("10.0.0.0/asd")}
75
+ end
76
+
77
+ def test_attributes
78
+ @valid_ipv4.each do |arg,attr|
79
+ ip = @klass.new(arg)
80
+ assert_equal attr.first, ip.address
81
+ assert_equal attr.last, ip.prefix.to_i
82
+ end
83
+ end
84
+
85
+ def test_octets
86
+ ip = @klass.new("10.1.2.3/8")
87
+ assert_equal ip.octets, [10,1,2,3]
88
+ end
89
+
90
+ def test_initialize_should_require_ip
91
+ assert_raise(ArgumentError) { @klass.new }
92
+ end
93
+
94
+ def test_method_data
95
+ assert_equal "\254\020\n\001", @ip.data
96
+ end
97
+
98
+ def test_method_to_s
99
+ @valid_ipv4.each do |arg,attr|
100
+ ip = @klass.new(arg)
101
+ assert_equal attr.join("/"), ip.to_s
102
+ end
103
+ end
104
+
105
+ def test_netmask
106
+ @netmask_values.each do |addr,mask|
107
+ ip = @klass.new(addr)
108
+ assert_equal mask, ip.netmask
109
+ end
110
+ end
111
+
112
+ def test_method_to_u32
113
+ @decimal_values.each do |addr,int|
114
+ ip = @klass.new(addr)
115
+ assert_equal int, ip.to_u32
116
+ end
117
+ end
118
+
119
+ def test_method_network?
120
+ assert_equal true, @network.network?
121
+ assert_equal false, @ip.network?
122
+ end
123
+
124
+ def test_method_broadcast
125
+ @broadcast.each do |addr,bcast|
126
+ ip = @klass.new(addr)
127
+ assert_instance_of @klass, ip.broadcast
128
+ assert_equal bcast, ip.broadcast.to_s
129
+ end
130
+ end
131
+
132
+ def test_method_network
133
+ @networks.each do |addr,net|
134
+ ip = @klass.new addr
135
+ assert_instance_of @klass, ip.network
136
+ assert_equal net, ip.network.to_s
137
+ end
138
+ end
139
+
140
+ def test_method_bits
141
+ ip = @klass.new("127.0.0.1")
142
+ assert_equal "01111111000000000000000000000001", ip.bits
143
+ end
144
+
145
+ def test_method_first
146
+ ip = @klass.new("192.168.100.0/24")
147
+ assert_instance_of @klass, ip.first
148
+ assert_equal "192.168.100.1/24", ip.first.to_s
149
+ ip = @klass.new("192.168.100.50/24")
150
+ assert_instance_of @klass, ip.first
151
+ assert_equal "192.168.100.1/24", ip.first.to_s
152
+ end
153
+
154
+ def test_method_last
155
+ ip = @klass.new("192.168.100.0/24")
156
+ assert_instance_of @klass, ip.last
157
+ assert_equal "192.168.100.254/24", ip.last.to_s
158
+ ip = @klass.new("192.168.100.50/24")
159
+ assert_instance_of @klass, ip.last
160
+ assert_equal "192.168.100.254/24", ip.last.to_s
161
+ end
162
+
163
+ def test_method_each_host
164
+ ip = @klass.new("10.0.0.1/29")
165
+ arr = []
166
+ ip.each_host {|i| arr << i.to_s}
167
+ expected = ["10.0.0.1/29","10.0.0.2/29","10.0.0.3/29",
168
+ "10.0.0.4/29","10.0.0.5/29","10.0.0.6/29"]
169
+ assert_equal expected, arr
170
+ end
171
+
172
+ def test_method_each
173
+ ip = @klass.new("10.0.0.1/29")
174
+ arr = []
175
+ ip.each {|i| arr << i.to_s}
176
+ expected = ["10.0.0.0/29","10.0.0.1/29","10.0.0.2/29",
177
+ "10.0.0.3/29","10.0.0.4/29","10.0.0.5/29",
178
+ "10.0.0.6/29","10.0.0.7/29"]
179
+ assert_equal expected, arr
180
+ end
181
+
182
+ def test_method_size
183
+ ip = @klass.new("10.0.0.1/29")
184
+ assert_equal 8, ip.size
185
+ end
186
+
187
+ def test_method_hosts
188
+ ip = @klass.new("10.0.0.1/29")
189
+ expected = ["10.0.0.1/29","10.0.0.2/29","10.0.0.3/29",
190
+ "10.0.0.4/29","10.0.0.5/29","10.0.0.6/29"]
191
+ assert_equal expected, ip.hosts.map {|i| i.to_s}
192
+ end
193
+
194
+ def test_method_network_u32
195
+ assert_equal 2886732288, @ip.network_u32
196
+ end
197
+
198
+ def test_method_broadcast_u32
199
+ assert_equal 2886732543, @ip.broadcast_u32
200
+ end
201
+
202
+ def test_method_include?
203
+ ip = @klass.new("192.168.10.100/24")
204
+ addr = @klass.new("192.168.10.102/24")
205
+ assert_equal true, ip.include?(addr)
206
+ assert_equal false, ip.include?(@klass.new("172.16.0.48"))
207
+ ip = @klass.new("10.0.0.0/8")
208
+ assert_equal true, ip.include?(@klass.new("10.0.0.0/9"))
209
+ assert_equal true, ip.include?(@klass.new("10.1.1.1/32"))
210
+ assert_equal true, ip.include?(@klass.new("10.1.1.1/9"))
211
+ assert_equal false, ip.include?(@klass.new("172.16.0.0/16"))
212
+ assert_equal false, ip.include?(@klass.new("10.0.0.0/7"))
213
+ assert_equal false, ip.include?(@klass.new("5.5.5.5/32"))
214
+ assert_equal false, ip.include?(@klass.new("11.0.0.0/8"))
215
+ ip = @klass.new("13.13.0.0/13")
216
+ assert_equal false, ip.include?(@klass.new("13.16.0.0/32"))
217
+ end
218
+
219
+ def test_method_octet
220
+ assert_equal 172, @ip[0]
221
+ assert_equal 16, @ip[1]
222
+ assert_equal 10, @ip[2]
223
+ assert_equal 1, @ip[3]
224
+ end
225
+
226
+ def test_method_a?
227
+ assert_equal true, @class_a.a?
228
+ assert_equal false, @class_b.a?
229
+ assert_equal false, @class_c.a?
230
+ end
231
+
232
+ def test_method_b?
233
+ assert_equal true, @class_b.b?
234
+ assert_equal false, @class_a.b?
235
+ assert_equal false, @class_c.b?
236
+ end
237
+
238
+ def test_method_c?
239
+ assert_equal true, @class_c.c?
240
+ assert_equal false, @class_a.c?
241
+ assert_equal false, @class_b.c?
242
+ end
243
+
244
+ def test_method_to_ipv6
245
+ assert_equal "ac10:0a01", @ip.to_ipv6
246
+ end
247
+
248
+ def test_method_reverse
249
+ assert_equal "1.10.16.172.in-addr.arpa", @ip.reverse
250
+ end
251
+
252
+ def test_method_comparabble
253
+ ip1 = @klass.new("10.1.1.1/8")
254
+ ip2 = @klass.new("10.1.1.1/16")
255
+ ip3 = @klass.new("172.16.1.1/14")
256
+ ip4 = @klass.new("10.1.1.1/8")
257
+
258
+ # ip1 should be major than ip2
259
+ assert_equal true, ip1 > ip2
260
+ assert_equal false, ip1 < ip2
261
+ assert_equal false, ip2 > ip1
262
+ # ip2 should be minor than ip3
263
+ assert_equal true, ip2 < ip3
264
+ assert_equal false, ip2 > ip3
265
+ # ip1 should be minor than ip3
266
+ assert_equal true, ip1 < ip3
267
+ assert_equal false, ip1 > ip3
268
+ assert_equal false, ip3 < ip1
269
+ # ip1 should be equal to itself
270
+ assert_equal true, ip1 == ip1
271
+ # ip1 should be equal to ip4
272
+ assert_equal true, ip1 == ip4
273
+ # test sorting
274
+ arr = ["10.1.1.1/16","10.1.1.1/8","172.16.1.1/14"]
275
+ assert_equal arr, [ip1,ip2,ip3].sort.map{|s| s.to_s}
276
+ end
277
+
278
+ def test_method_minus
279
+ ip1 = @klass.new("10.1.1.1/8")
280
+ ip2 = @klass.new("10.1.1.10/8")
281
+ assert_equal 9, ip2 - ip1
282
+ assert_equal 9, ip1 - ip2
283
+ end
284
+
285
+ def test_method_plus
286
+ ip1 = @klass.new("172.16.10.1/24")
287
+ ip2 = @klass.new("172.16.11.2/24")
288
+ assert_equal "172.16.10.0/23", (ip1 + ip2).to_s
289
+ ip2 = @klass.new("172.16.12.2/24")
290
+ assert_equal [ip1.network.to_s,ip2.network.to_s], (ip1 + ip2).map{|i| i.to_s}
291
+ end
292
+
293
+
294
+ def test_method_netmask_equal
295
+ ip = @klass.new("10.1.1.1/16")
296
+ assert_equal 16, ip.prefix.to_i
297
+ ip.netmask = "255.255.255.0"
298
+ assert_equal 24, ip.prefix.to_i
299
+ end
300
+
301
+ def test_method_subnet
302
+ assert_raise(ArgumentError) {@ip.subnet(0)}
303
+ assert_raise(ArgumentError) {@ip.subnet(257)}
304
+
305
+ arr = ["172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27",
306
+ "172.16.10.96/27", "172.16.10.128/27", "172.16.10.160/27",
307
+ "172.16.10.192/27", "172.16.10.224/27"]
308
+ assert_equal arr, @network.subnet(8).map {|s| s.to_s}
309
+ arr = ["172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27",
310
+ "172.16.10.96/27", "172.16.10.128/27", "172.16.10.160/27",
311
+ "172.16.10.192/26"]
312
+ assert_equal arr, @network.subnet(7).map {|s| s.to_s}
313
+ arr = ["172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27",
314
+ "172.16.10.96/27", "172.16.10.128/26", "172.16.10.192/26"]
315
+ assert_equal arr, @network.subnet(6).map {|s| s.to_s}
316
+ arr = ["172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27",
317
+ "172.16.10.96/27", "172.16.10.128/25"]
318
+ assert_equal arr, @network.subnet(5).map {|s| s.to_s}
319
+ arr = ["172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/26",
320
+ "172.16.10.192/26"]
321
+ assert_equal arr, @network.subnet(4).map {|s| s.to_s}
322
+ arr = ["172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/25"]
323
+ assert_equal arr, @network.subnet(3).map {|s| s.to_s}
324
+ arr = ["172.16.10.0/25", "172.16.10.128/25"]
325
+ assert_equal arr, @network.subnet(2).map {|s| s.to_s}
326
+ arr = ["172.16.10.0/24"]
327
+ assert_equal arr, @network.subnet(1).map {|s| s.to_s}
328
+ end
329
+
330
+ def test_method_supernet
331
+ assert_raise(ArgumentError) {@ip.supernet(0)}
332
+ assert_raise(ArgumentError) {@ip.supernet(24)}
333
+ assert_equal "172.16.10.0/23", @ip.supernet(23).to_s
334
+ assert_equal "172.16.8.0/22", @ip.supernet(22).to_s
335
+ end
336
+
337
+ def test_classmethod_parse_u32
338
+ @decimal_values.each do |addr,int|
339
+ ip = @klass.parse_u32(int)
340
+ ip.prefix = addr.split("/").last.to_i
341
+ assert_equal ip.to_s, addr
342
+ end
343
+ end
344
+
345
+ def test_classhmethod_extract
346
+ str = "foobar172.16.10.1barbaz"
347
+ assert_equal "172.16.10.1/16", @klass.extract(str).to_s
348
+ end
349
+
350
+ def test_classmethod_summarize
351
+
352
+ # Should return self if only one network given
353
+ assert_equal @ip, @klass.summarize(@ip)
354
+
355
+ # Summarize homogeneous networks
356
+ ip1 = @klass.new("172.16.10.1/24")
357
+ ip2 = @klass.new("172.16.11.2/24")
358
+ assert_equal "172.16.10.0/23", @klass.summarize(ip1,ip2).to_s
359
+
360
+ ip1 = @klass.new("10.0.0.1/24")
361
+ ip2 = @klass.new("10.0.1.1/24")
362
+ ip3 = @klass.new("10.0.2.1/24")
363
+ ip4 = @klass.new("10.0.3.1/24")
364
+ assert_equal "10.0.0.0/22", @klass.summarize(ip1,ip2,ip3,ip4).to_s
365
+
366
+ # Summarize non homogeneous networks
367
+ ip1 = @klass.new("10.0.1.1/24")
368
+ ip2 = @klass.new("10.0.2.1/24")
369
+ ip3 = @klass.new("10.0.3.1/24")
370
+ ip4 = @klass.new("10.0.4.1/24")
371
+ result = ["10.0.1.0/24","10.0.2.0/23","10.0.4.0/24"]
372
+ assert_equal result, @klass.summarize(ip1,ip2,ip3,ip4).map{|i| i.to_s}
373
+
374
+ ip1 = @klass.new("10.0.1.1/24")
375
+ ip2 = @klass.new("10.10.2.1/24")
376
+ ip3 = @klass.new("172.16.0.1/24")
377
+ ip4 = @klass.new("172.16.1.1/24")
378
+ result = ["10.0.1.0/24","10.10.2.0/24","172.16.0.0/23"]
379
+ assert_equal result, @klass.summarize(ip1,ip2,ip3,ip4).map{|i| i.to_s}
380
+
381
+ end
382
+
383
+ def test_classmethod_parse_data
384
+ ip = @klass.parse_data "\254\020\n\001"
385
+ assert_instance_of @klass, ip
386
+ assert_equal "172.16.10.1", ip.address
387
+ assert_equal "172.16.10.1/16", ip.to_s
388
+ end
389
+
390
+ end # class IPv4Test
391
+
392
+