ipaddress 0.7.5 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +13 -0
- data/README.rdoc +106 -80
- data/VERSION +1 -1
- data/ipaddress.gemspec +55 -0
- data/lib/ipaddress.rb +16 -2
- data/lib/ipaddress/ipv4.rb +76 -68
- data/lib/ipaddress/ipv6.rb +132 -22
- data/lib/ipaddress/prefix.rb +14 -1
- data/test/ipaddress/ipv4_test.rb +65 -43
- data/test/ipaddress/ipv6_test.rb +68 -2
- metadata +26 -48
- data/lib/ipaddress/extensions/extensions.rb +0 -22
- data/test/ipaddress/extensions/extensions_test.rb +0 -18
data/lib/ipaddress/ipv6.rb
CHANGED
@@ -22,7 +22,7 @@ module IPAddress;
|
|
22
22
|
# bits or two octect. For example, the following is a valid IPv6
|
23
23
|
# address:
|
24
24
|
#
|
25
|
-
#
|
25
|
+
# 2001:0db8:0000:0000:0008:0800:200c:417a
|
26
26
|
#
|
27
27
|
# Letters in an IPv6 address are usually written downcase, as per
|
28
28
|
# RFC. You can create a new IPv6 object using uppercase letters, but
|
@@ -42,7 +42,7 @@ module IPAddress;
|
|
42
42
|
# Using compression, the IPv6 address written above can be shorten into
|
43
43
|
# the following, equivalent, address
|
44
44
|
#
|
45
|
-
#
|
45
|
+
# 2001:db8::8:800:200c:417a
|
46
46
|
#
|
47
47
|
# This short version is often used in human representation.
|
48
48
|
#
|
@@ -51,7 +51,7 @@ module IPAddress;
|
|
51
51
|
# As we used to do with IPv4 addresses, an IPv6 address can be written
|
52
52
|
# using the prefix notation to specify the subnet mask:
|
53
53
|
#
|
54
|
-
#
|
54
|
+
# 2001:db8::8:800:200c:417a/64
|
55
55
|
#
|
56
56
|
# The /64 part means that the first 64 bits of the address are
|
57
57
|
# representing the network portion, and the last 64 bits are the host
|
@@ -75,9 +75,9 @@ module IPAddress;
|
|
75
75
|
#
|
76
76
|
# An IPv6 address can be expressed in any of the following forms:
|
77
77
|
#
|
78
|
-
# * "
|
79
|
-
# * "
|
80
|
-
# * "
|
78
|
+
# * "2001:0db8:0000:0000:0008:0800:200C:417A": IPv6 address with no compression
|
79
|
+
# * "2001:db8:0:0:8:800:200C:417A": IPv6 address with leading zeros compression
|
80
|
+
# * "2001:db8::8:800:200C:417A": IPv6 address with full compression
|
81
81
|
#
|
82
82
|
# In all these 3 cases, a new IPv6 address object will be created, using the default
|
83
83
|
# subnet mask /128
|
@@ -328,6 +328,36 @@ module IPAddress;
|
|
328
328
|
to_u128 & @prefix.to_u128
|
329
329
|
end
|
330
330
|
|
331
|
+
#
|
332
|
+
# Returns the broadcast address in Unsigned 128bits format
|
333
|
+
#
|
334
|
+
# ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
|
335
|
+
#
|
336
|
+
# ip6.broadcast_u128
|
337
|
+
# #=> 42540766411282592875350729025363378175
|
338
|
+
#
|
339
|
+
# Please note that there is no Broadcast concept in IPv6
|
340
|
+
# addresses as in IPv4 addresses, and this method is just
|
341
|
+
# an helper to other functions.
|
342
|
+
#
|
343
|
+
def broadcast_u128
|
344
|
+
network_u128 + size - 1
|
345
|
+
end
|
346
|
+
|
347
|
+
#
|
348
|
+
# Returns the number of IP addresses included
|
349
|
+
# in the network. It also counts the network
|
350
|
+
# address and the broadcast address.
|
351
|
+
#
|
352
|
+
# ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
|
353
|
+
#
|
354
|
+
# ip6.size
|
355
|
+
# #=> 18446744073709551616
|
356
|
+
#
|
357
|
+
def size
|
358
|
+
2 ** @prefix.host_prefix
|
359
|
+
end
|
360
|
+
|
331
361
|
#
|
332
362
|
# Checks whether a subnet includes the given IP address.
|
333
363
|
#
|
@@ -384,7 +414,74 @@ module IPAddress;
|
|
384
414
|
def mapped?
|
385
415
|
to_u128 >> 32 == 0xffff
|
386
416
|
end
|
387
|
-
|
417
|
+
|
418
|
+
#
|
419
|
+
# Iterates over all the IP addresses for the given
|
420
|
+
# network (or IP address).
|
421
|
+
#
|
422
|
+
# The object yielded is a new IPv6 object created
|
423
|
+
# from the iteration.
|
424
|
+
#
|
425
|
+
# ip6 = IPAddress("2001:db8::4/125")
|
426
|
+
#
|
427
|
+
# ip6.each do |i|
|
428
|
+
# p i.compressed
|
429
|
+
# end
|
430
|
+
# #=> "2001:db8::"
|
431
|
+
# #=> "2001:db8::1"
|
432
|
+
# #=> "2001:db8::2"
|
433
|
+
# #=> "2001:db8::3"
|
434
|
+
# #=> "2001:db8::4"
|
435
|
+
# #=> "2001:db8::5"
|
436
|
+
# #=> "2001:db8::6"
|
437
|
+
# #=> "2001:db8::7"
|
438
|
+
#
|
439
|
+
# WARNING: if the host portion is very large, this method
|
440
|
+
# can be very slow and possibly hang your system!
|
441
|
+
#
|
442
|
+
def each
|
443
|
+
(network_u128..broadcast_u128).each do |i|
|
444
|
+
yield self.class.parse_u128(i, @prefix)
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
#
|
449
|
+
# Spaceship operator to compare IPv6 objects
|
450
|
+
#
|
451
|
+
# Comparing IPv6 addresses is useful to ordinate
|
452
|
+
# them into lists that match our intuitive
|
453
|
+
# perception of ordered IP addresses.
|
454
|
+
#
|
455
|
+
# The first comparison criteria is the u128 value.
|
456
|
+
# For example, 2001:db8:1::1 will be considered
|
457
|
+
# to be less than 2001:db8:2::1, because, in a ordered list,
|
458
|
+
# we expect 2001:db8:1::1 to come before 2001:db8:2::1.
|
459
|
+
#
|
460
|
+
# The second criteria, in case two IPv6 objects
|
461
|
+
# have identical addresses, is the prefix. An higher
|
462
|
+
# prefix will be considered greater than a lower
|
463
|
+
# prefix. This is because we expect to see
|
464
|
+
# 2001:db8:1::1/64 come before 2001:db8:1::1/65
|
465
|
+
#
|
466
|
+
# Example:
|
467
|
+
#
|
468
|
+
# ip1 = IPAddress "2001:db8:1::1/64"
|
469
|
+
# ip2 = IPAddress "2001:db8:2::1/64"
|
470
|
+
# ip3 = IPAddress "2001:db8:1::1/65"
|
471
|
+
#
|
472
|
+
# ip1 < ip2
|
473
|
+
# #=> true
|
474
|
+
# ip1 < ip3
|
475
|
+
# #=> false
|
476
|
+
#
|
477
|
+
# [ip1,ip2,ip3].sort.map{|i| i.to_string}
|
478
|
+
# #=> ["2001:db8:1::1/64","2001:db8:1::1/65","2001:db8:2::1/64"]
|
479
|
+
#
|
480
|
+
def <=>(oth)
|
481
|
+
return prefix <=> oth.prefix if to_u128 == oth.to_u128
|
482
|
+
to_u128 <=> oth.to_u128
|
483
|
+
end
|
484
|
+
|
388
485
|
#
|
389
486
|
# Returns the address portion of an IP in binary format,
|
390
487
|
# as a string containing a sequence of 0 and 1
|
@@ -430,6 +527,19 @@ module IPAddress;
|
|
430
527
|
@address.gsub(":","-") + ".ipv6-literal.net"
|
431
528
|
end
|
432
529
|
|
530
|
+
#
|
531
|
+
# Returns a new IPv6 object with the network number
|
532
|
+
# for the given IP.
|
533
|
+
#
|
534
|
+
# ip = IPAddress "2001:db8:1:1:1:1:1:1/32"
|
535
|
+
#
|
536
|
+
# ip.network.to_string
|
537
|
+
# #=> "2001:db8::/32"
|
538
|
+
#
|
539
|
+
def network
|
540
|
+
self.class.parse_u128(network_u128, @prefix)
|
541
|
+
end
|
542
|
+
|
433
543
|
#
|
434
544
|
# Extract 16 bits groups from a string
|
435
545
|
#
|
@@ -470,18 +580,18 @@ module IPAddress;
|
|
470
580
|
# Creates a new IPv6 object from an
|
471
581
|
# unsigned 128 bits integer.
|
472
582
|
#
|
473
|
-
# ip6 = IPAddress::IPv6::parse_u128(
|
583
|
+
# ip6 = IPAddress::IPv6::parse_u128(42540766411282592856906245548098208122)
|
474
584
|
# ip6.prefix = 64
|
475
585
|
#
|
476
|
-
# ip6.
|
477
|
-
# #=> "
|
586
|
+
# ip6.to_string
|
587
|
+
# #=> "2001:db8::8:800:200c:417a/64"
|
478
588
|
#
|
479
589
|
# The +prefix+ parameter is optional:
|
480
590
|
#
|
481
|
-
# ip6 = IPAddress::IPv6::parse_u128(
|
591
|
+
# ip6 = IPAddress::IPv6::parse_u128(42540766411282592856906245548098208122, 64)
|
482
592
|
#
|
483
|
-
# ip6.
|
484
|
-
# #=> "
|
593
|
+
# ip6.to_string
|
594
|
+
# #=> "2001:db8::8:800:200c:417a/64"
|
485
595
|
#
|
486
596
|
def self.parse_u128(u128, prefix=128)
|
487
597
|
str = IN6FORMAT % (0..7).map{|i| (u128>>(112-16*i))&0xffff}
|
@@ -495,15 +605,15 @@ module IPAddress;
|
|
495
605
|
# ip6 = IPAddress::IPv6::parse_hex("20010db80000000000080800200c417a")
|
496
606
|
# ip6.prefix = 64
|
497
607
|
#
|
498
|
-
# ip6.
|
608
|
+
# ip6.to_string
|
499
609
|
# #=> "2001:db8::8:800:200c:417a/64"
|
500
610
|
#
|
501
611
|
# The +prefix+ parameter is optional:
|
502
612
|
#
|
503
613
|
# ip6 = IPAddress::IPv6::parse_hex("20010db80000000000080800200c417a", 64)
|
504
614
|
#
|
505
|
-
# ip6.
|
506
|
-
# #=> "
|
615
|
+
# ip6.to_string
|
616
|
+
# #=> "2001:db8::8:800:200c:417a/64"
|
507
617
|
#
|
508
618
|
def self.parse_hex(hex, prefix=128)
|
509
619
|
self.parse_u128(hex.hex, prefix)
|
@@ -605,14 +715,14 @@ module IPAddress;
|
|
605
715
|
#
|
606
716
|
# ip = IPAddress::IPv6::Loopback.new
|
607
717
|
#
|
608
|
-
# ip.
|
718
|
+
# ip.to_string
|
609
719
|
# #=> "::1/128"
|
610
720
|
#
|
611
721
|
# or by using the wrapper:
|
612
722
|
#
|
613
723
|
# ip = IPAddress "::1"
|
614
724
|
#
|
615
|
-
# ip.
|
725
|
+
# ip.to_string
|
616
726
|
# #=> "::1/128"
|
617
727
|
#
|
618
728
|
# Checking if an address is loopback is easy with the IPv6#loopback?
|
@@ -629,7 +739,7 @@ module IPAddress;
|
|
629
739
|
#
|
630
740
|
# ip = IPAddress::IPv6::Loopback.new
|
631
741
|
#
|
632
|
-
# ip.
|
742
|
+
# ip.to_string
|
633
743
|
# #=> "::1/128"
|
634
744
|
#
|
635
745
|
def initialize
|
@@ -668,7 +778,7 @@ module IPAddress;
|
|
668
778
|
# ip6.mapped?
|
669
779
|
# #=> true
|
670
780
|
#
|
671
|
-
# ip6.
|
781
|
+
# ip6.to_string
|
672
782
|
# #=> "::FFFF:172.16.10.1/128"
|
673
783
|
#
|
674
784
|
# Now with the +ipv4+ attribute, we can easily access the IPv4 portion
|
@@ -695,7 +805,7 @@ module IPAddress;
|
|
695
805
|
# That is, two colons and the IPv4 address. However, as by RFC, the ffff
|
696
806
|
# group will be automatically added at the beginning
|
697
807
|
#
|
698
|
-
# ip6.
|
808
|
+
# ip6.to_string
|
699
809
|
# => "::ffff:172.16.10.1/128"
|
700
810
|
#
|
701
811
|
# making it a mapped IPv6 compatible address.
|
@@ -718,7 +828,7 @@ module IPAddress;
|
|
718
828
|
#
|
719
829
|
# ip6 = IPAddress::IPv6::Mapped.new "::0d01:4403"
|
720
830
|
#
|
721
|
-
# ip6.
|
831
|
+
# ip6.to_string
|
722
832
|
# #=> "::ffff:13.1.68.3"
|
723
833
|
#
|
724
834
|
def initialize(str)
|
data/lib/ipaddress/prefix.rb
CHANGED
@@ -18,7 +18,7 @@ module IPAddress
|
|
18
18
|
# IPAddress::Prefix shouldn't be accesses directly, unless
|
19
19
|
# for particular needs.
|
20
20
|
#
|
21
|
-
class Prefix
|
21
|
+
class Prefix
|
22
22
|
|
23
23
|
include Comparable
|
24
24
|
|
@@ -247,6 +247,19 @@ module IPAddress
|
|
247
247
|
bits.to_i(2)
|
248
248
|
end
|
249
249
|
|
250
|
+
#
|
251
|
+
# Returns the length of the host portion
|
252
|
+
# of a netmask.
|
253
|
+
#
|
254
|
+
# prefix = Prefix128.new 96
|
255
|
+
#
|
256
|
+
# prefix.host_prefix
|
257
|
+
# #=> 32
|
258
|
+
#
|
259
|
+
def host_prefix
|
260
|
+
128 - @prefix
|
261
|
+
end
|
262
|
+
|
250
263
|
end # class Prefix123 < Prefix
|
251
264
|
|
252
265
|
end # module IPAddress
|
data/test/ipaddress/ipv4_test.rb
CHANGED
@@ -304,20 +304,20 @@ class IPv4Test < Test::Unit::TestCase
|
|
304
304
|
assert_equal "1.10.16.172.in-addr.arpa", @ip.reverse
|
305
305
|
end
|
306
306
|
|
307
|
-
def
|
307
|
+
def test_method_compare
|
308
308
|
ip1 = @klass.new("10.1.1.1/8")
|
309
309
|
ip2 = @klass.new("10.1.1.1/16")
|
310
310
|
ip3 = @klass.new("172.16.1.1/14")
|
311
311
|
ip4 = @klass.new("10.1.1.1/8")
|
312
312
|
|
313
|
-
#
|
314
|
-
assert_equal true, ip1
|
315
|
-
assert_equal false, ip1
|
316
|
-
assert_equal false, ip2
|
317
|
-
# ip2 should be
|
313
|
+
# ip2 should be greater than ip1
|
314
|
+
assert_equal true, ip1 < ip2
|
315
|
+
assert_equal false, ip1 > ip2
|
316
|
+
assert_equal false, ip2 < ip1
|
317
|
+
# ip2 should be less than ip3
|
318
318
|
assert_equal true, ip2 < ip3
|
319
319
|
assert_equal false, ip2 > ip3
|
320
|
-
# ip1 should be
|
320
|
+
# ip1 should be less than ip3
|
321
321
|
assert_equal true, ip1 < ip3
|
322
322
|
assert_equal false, ip1 > ip3
|
323
323
|
assert_equal false, ip3 < ip1
|
@@ -326,7 +326,13 @@ class IPv4Test < Test::Unit::TestCase
|
|
326
326
|
# ip1 should be equal to ip4
|
327
327
|
assert_equal true, ip1 == ip4
|
328
328
|
# test sorting
|
329
|
-
arr = ["10.1.1.1/
|
329
|
+
arr = ["10.1.1.1/8","10.1.1.1/16","172.16.1.1/14"]
|
330
|
+
assert_equal arr, [ip1,ip2,ip3].sort.map{|s| s.to_string}
|
331
|
+
# test same prefix
|
332
|
+
ip1 = @klass.new("10.0.0.0/24")
|
333
|
+
ip2 = @klass.new("10.0.0.0/16")
|
334
|
+
ip3 = @klass.new("10.0.0.0/8")
|
335
|
+
arr = ["10.0.0.0/8","10.0.0.0/16","10.0.0.0/24"]
|
330
336
|
assert_equal arr, [ip1,ip2,ip3].sort.map{|s| s.to_string}
|
331
337
|
end
|
332
338
|
|
@@ -371,41 +377,57 @@ class IPv4Test < Test::Unit::TestCase
|
|
371
377
|
assert_equal 24, ip.prefix.to_i
|
372
378
|
end
|
373
379
|
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
380
|
+
def test_method_split
|
381
|
+
assert_raise(ArgumentError) {@ip.split(0)}
|
382
|
+
assert_raise(ArgumentError) {@ip.split(257)}
|
383
|
+
|
384
|
+
assert_equal @ip.network, @ip.split(1).first
|
385
|
+
|
386
|
+
arr = ["172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27",
|
387
|
+
"172.16.10.96/27", "172.16.10.128/27", "172.16.10.160/27",
|
388
|
+
"172.16.10.192/27", "172.16.10.224/27"]
|
389
|
+
assert_equal arr, @network.split(8).map {|s| s.to_string}
|
390
|
+
arr = ["172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27",
|
391
|
+
"172.16.10.96/27", "172.16.10.128/27", "172.16.10.160/27",
|
392
|
+
"172.16.10.192/26"]
|
393
|
+
assert_equal arr, @network.split(7).map {|s| s.to_string}
|
394
|
+
arr = ["172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27",
|
395
|
+
"172.16.10.96/27", "172.16.10.128/26", "172.16.10.192/26"]
|
396
|
+
assert_equal arr, @network.split(6).map {|s| s.to_string}
|
397
|
+
arr = ["172.16.10.0/27", "172.16.10.32/27", "172.16.10.64/27",
|
398
|
+
"172.16.10.96/27", "172.16.10.128/25"]
|
399
|
+
assert_equal arr, @network.split(5).map {|s| s.to_string}
|
400
|
+
arr = ["172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/26",
|
401
|
+
"172.16.10.192/26"]
|
402
|
+
assert_equal arr, @network.split(4).map {|s| s.to_string}
|
403
|
+
arr = ["172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/25"]
|
404
|
+
assert_equal arr, @network.split(3).map {|s| s.to_string}
|
405
|
+
arr = ["172.16.10.0/25", "172.16.10.128/25"]
|
406
|
+
assert_equal arr, @network.split(2).map {|s| s.to_string}
|
407
|
+
arr = ["172.16.10.0/24"]
|
408
|
+
assert_equal arr, @network.split(1).map {|s| s.to_string}
|
409
|
+
end
|
410
|
+
|
411
|
+
def test_method_subnet
|
412
|
+
assert_raise(ArgumentError) {@network.subnet(23)}
|
413
|
+
assert_raise(ArgumentError) {@network.subnet(33)}
|
414
|
+
assert_nothing_raised {@ip.subnet(30)}
|
415
|
+
arr = ["172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/26",
|
416
|
+
"172.16.10.192/26"]
|
417
|
+
assert_equal arr, @network.subnet(26).map {|s| s.to_string}
|
418
|
+
arr = ["172.16.10.0/25", "172.16.10.128/25"]
|
419
|
+
assert_equal arr, @network.subnet(25).map {|s| s.to_string}
|
420
|
+
arr = ["172.16.10.0/24"]
|
421
|
+
assert_equal arr, @network.subnet(24).map {|s| s.to_string}
|
422
|
+
end
|
423
|
+
|
424
|
+
def test_method_supernet
|
425
|
+
assert_raise(ArgumentError) {@ip.supernet(24)}
|
426
|
+
assert_equal "0.0.0.0/0", @ip.supernet(0).to_string
|
427
|
+
assert_equal "0.0.0.0/0", @ip.supernet(-2).to_string
|
428
|
+
assert_equal "172.16.10.0/23", @ip.supernet(23).to_string
|
429
|
+
assert_equal "172.16.8.0/22", @ip.supernet(22).to_string
|
430
|
+
end
|
409
431
|
|
410
432
|
def test_classmethod_parse_u32
|
411
433
|
@decimal_values.each do |addr,int|
|
data/test/ipaddress/ipv6_test.rb
CHANGED
@@ -32,6 +32,11 @@ class IPv6Test < Test::Unit::TestCase
|
|
32
32
|
|
33
33
|
@invalid_ipv6 = [":1:2:3:4:5:6:7",
|
34
34
|
":1:2:3:4:5:6:7"]
|
35
|
+
|
36
|
+
@networks = {
|
37
|
+
"2001:db8:1:1:1:1:1:1/32" => "2001:db8::/32",
|
38
|
+
"2001:db8:1:1:1:1:1::/32" => "2001:db8::/32",
|
39
|
+
"2001:db8::1/64" => "2001:db8::/64"}
|
35
40
|
|
36
41
|
@ip = @klass.new "2001:db8::8:800:200c:417a/64"
|
37
42
|
@network = @klass.new "2001:db8:8:800::/64"
|
@@ -122,7 +127,22 @@ class IPv6Test < Test::Unit::TestCase
|
|
122
127
|
def test_method_network_u128
|
123
128
|
assert_equal 42540766411282592856903984951653826560, @ip.network_u128
|
124
129
|
end
|
125
|
-
|
130
|
+
|
131
|
+
def test_method_broadcast_u128
|
132
|
+
assert_equal 42540766411282592875350729025363378175, @ip.broadcast_u128
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_method_size
|
136
|
+
ip = @klass.new("2001:db8::8:800:200c:417a/64")
|
137
|
+
assert_equal 2**64, ip.size
|
138
|
+
ip = @klass.new("2001:db8::8:800:200c:417a/32")
|
139
|
+
assert_equal 2**96, ip.size
|
140
|
+
ip = @klass.new("2001:db8::8:800:200c:417a/120")
|
141
|
+
assert_equal 2**8, ip.size
|
142
|
+
ip = @klass.new("2001:db8::8:800:200c:417a/124")
|
143
|
+
assert_equal 2**4, ip.size
|
144
|
+
end
|
145
|
+
|
126
146
|
def test_method_include?
|
127
147
|
assert_equal true, @ip.include?(@ip)
|
128
148
|
# test prefix on same address
|
@@ -186,7 +206,53 @@ class IPv6Test < Test::Unit::TestCase
|
|
186
206
|
assert_equal true, @klass.new("::1").loopback?
|
187
207
|
assert_equal false, @ip.loopback?
|
188
208
|
end
|
189
|
-
|
209
|
+
|
210
|
+
def test_method_network
|
211
|
+
@networks.each do |addr,net|
|
212
|
+
ip = @klass.new addr
|
213
|
+
assert_instance_of @klass, ip.network
|
214
|
+
assert_equal net, ip.network.to_string
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_method_each
|
219
|
+
ip = @klass.new("2001:db8::4/125")
|
220
|
+
arr = []
|
221
|
+
ip.each {|i| arr << i.compressed}
|
222
|
+
expected = ["2001:db8::","2001:db8::1","2001:db8::2",
|
223
|
+
"2001:db8::3","2001:db8::4","2001:db8::5",
|
224
|
+
"2001:db8::6","2001:db8::7"]
|
225
|
+
assert_equal expected, arr
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_method_compare
|
229
|
+
ip1 = @klass.new("2001:db8:1::1/64")
|
230
|
+
ip2 = @klass.new("2001:db8:2::1/64")
|
231
|
+
ip3 = @klass.new("2001:db8:1::2/64")
|
232
|
+
ip4 = @klass.new("2001:db8:1::1/65")
|
233
|
+
|
234
|
+
# ip2 should be greater than ip1
|
235
|
+
assert_equal true, ip2 > ip1
|
236
|
+
assert_equal false, ip1 > ip2
|
237
|
+
assert_equal false, ip2 < ip1
|
238
|
+
# ip3 should be less than ip2
|
239
|
+
assert_equal true, ip2 > ip3
|
240
|
+
assert_equal false, ip2 < ip3
|
241
|
+
# ip1 should be less than ip3
|
242
|
+
assert_equal true, ip1 < ip3
|
243
|
+
assert_equal false, ip1 > ip3
|
244
|
+
assert_equal false, ip3 < ip1
|
245
|
+
# ip1 should be equal to itself
|
246
|
+
assert_equal true, ip1 == ip1
|
247
|
+
# ip4 should be greater than ip1
|
248
|
+
assert_equal true, ip1 < ip4
|
249
|
+
assert_equal false, ip1 > ip4
|
250
|
+
# test sorting
|
251
|
+
arr = ["2001:db8:1::1/64","2001:db8:1::1/65",
|
252
|
+
"2001:db8:1::2/64","2001:db8:2::1/64"]
|
253
|
+
assert_equal arr, [ip1,ip2,ip3,ip4].sort.map{|s| s.to_string}
|
254
|
+
end
|
255
|
+
|
190
256
|
def test_classmethod_expand
|
191
257
|
compressed = "2001:db8:0:cd30::"
|
192
258
|
expanded = "2001:0db8:0000:cd30:0000:0000:0000:0000"
|