ipaddress_2 0.11.0 → 0.14.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64e253cbf0ced3857087c448ed2308037465bb3ed59162c0b90348df5f3986c7
4
- data.tar.gz: c2c11d0cf5e6a2811097e5365cf14f19d53052d98e5ba2abf7565ac24365b353
3
+ metadata.gz: 359df425a73931023ee0026c8fdb2819f43117e24e1aa24b5ff7bb3d7f6121f6
4
+ data.tar.gz: db06b07d89444432225af2e82529a0eca395cda6e42ed59bf0cf443befc914c8
5
5
  SHA512:
6
- metadata.gz: 9f399ef081ca059f28e465e969f3b1f430a2eecd0d9b171d74b5d2191e9aee83cd09c5fb68fcda7d8d71457a5621803e33a67c19a700383f6e330ce4f772973e
7
- data.tar.gz: acbced5a8b91d5c5da3b123d69d22a3d701e37f92365250f7328788749639bcca5559053ecf4019095b12e2d3b0b6c44d8f21b55cac3bcc856df8583102b9494
6
+ metadata.gz: b537db60dfaf772c2162d3c1f52c0066b0737af5811fa0ac1894aa86414ce86950f4bba00c8aa3c3a1c1171937de26848933020ce428f5b7df04611a08bcf19f
7
+ data.tar.gz: e2632e98d23618da97172f711d1736d7b6845105cb53412c42db5caa6326edc66b9e1f1ec2319f61855d1c54f3fa743df02cd653a6fd86f933b4f5d9944392f3
data/.travis.yml CHANGED
@@ -4,6 +4,8 @@ rvm:
4
4
  - 2.4
5
5
  - 2.5
6
6
  - 2.6
7
+ - 2.7
8
+ - 3.0
7
9
  install:
8
10
  - gem install bundler
9
11
  - gem install rake
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## 0.14.0
4
+
5
+ ### Enhancements
6
+ * include? will now accept a string. Will also work for include_all?
7
+
8
+ ## 0.13.0
9
+
10
+ ### Enhancements
11
+ * Provide arithmetic operations on IPv4 and IPv6
12
+
13
+ ## 0.12.1
14
+
15
+ ### Bugfix
16
+ * Remove dup from IPv6 summarization to slightly improve performance
17
+
18
+ ## 0.12.0
19
+
20
+ ### Enhancements
21
+ * Added 'last' to IPv6
22
+ * Added 'broadcast' to IPv6
23
+
24
+ ## 0.11.1
25
+
26
+ ### Bugfix
27
+ * Fix prefix change in find\_adjacent
28
+
3
29
  ## 0.11.0
4
30
 
5
31
  ### Enhancements
@@ -26,6 +52,6 @@
26
52
  ### Bugfix
27
53
  * Removed duplicate link_local? in IPv6
28
54
 
29
- Please check [CHANGELOG.rdoc](https://github.com/ipaddress2-gem/ipaddress2/blob/master/CHANGELOG.rdoc) for previous changes.
55
+ Please check [CHANGELOG.rdoc](https://github.com/ipaddress2-gem/ipaddress_2/blob/master/CHANGELOG.rdoc) for previous changes.
30
56
 
31
57
 
data/README.rdoc CHANGED
@@ -16,11 +16,11 @@ examples of typical usage.
16
16
 
17
17
  * Ruby 1.9.3 or later
18
18
 
19
- Please refer to {Travis CI}[https://travis-ci.org/ipaddress2-gem/ipaddress2] for Build Tests on specific versions of Ruby.
19
+ Please refer to {Travis CI}[https://travis-ci.org/ipaddress2-gem/ipaddress_2] for Build Tests on specific versions of Ruby.
20
20
 
21
- {<img src="https://travis-ci.org/ipaddress2-gem/ipaddress2.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/ipaddress2-gem/ipaddress2] {<img src="https://codeclimate.com/github/ipaddress2-gem/ipaddress2/badges/gpa.svg" />}[https://codeclimate.com/github/ipaddress2-gem/ipaddress2]
21
+ {<img src="https://travis-ci.org/ipaddress2-gem/ipaddress_2.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/ipaddress2-gem/ipaddress_2] {<img src="https://codeclimate.com/github/ipaddress2-gem/ipaddress_2/badges/gpa.svg" />}[https://codeclimate.com/github/ipaddress2-gem/ipaddress_2]
22
22
 
23
- If you want to contribute, please refer to {Contributing.md}[https://github.com/ipaddress2-gem/ipaddress2/blob/master/CONTRIBUTING.md].
23
+ If you want to contribute, please refer to {Contributing.md}[https://github.com/ipaddress2-gem/ipaddress_2/blob/master/CONTRIBUTING.md].
24
24
 
25
25
 
26
26
  == Installation
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.0
1
+ 0.14.0
data/ipaddress_2.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.version = IPAddress::VERSION
10
10
  s.require_paths = ["lib"]
11
11
  s.authors = ["bluemonk", "mikemackintosh"]
12
- s.description = "IPAddress2 is a Ruby library designed to make manipulation\n of IPv4 and IPv6 addresses both powerful and simple. It mantains\n a layer of compatibility with Ruby's own IPAddr, while\n addressing many of its issues."
12
+ s.description = "IPAddress2 is a Ruby library designed to make manipulation\n of IPv4 and IPv6 addresses both powerful and simple. It maintains\n a layer of compatibility with Ruby's own IPAddr, while\n addressing many of its issues."
13
13
  s.email = "adam@21eleven.com"
14
14
  s.extra_rdoc_files = [
15
15
  "CHANGELOG.rdoc",
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
  "README.rdoc"
18
18
  ]
19
19
  s.files = `git ls-files -z`.split("\x0")
20
- s.homepage = "https://github.com/ipaddress2-gem/ipaddress2"
20
+ s.homepage = "https://github.com/ipaddress2-gem/ipaddress_2"
21
21
 
22
22
  s.add_development_dependency "bundler"
23
23
  s.add_development_dependency "rake"
@@ -377,6 +377,18 @@ module IPAddress;
377
377
  def network
378
378
  self.class.parse_u32(network_u32, @prefix)
379
379
  end
380
+
381
+ #
382
+ # Returns a new IPv4 object containing only the host part of this IP.
383
+ #
384
+ # ip = IPAddress("172.16.10.64/24")
385
+ #
386
+ # ip.hostpart.to_s
387
+ # #=> "0.0.0.64"
388
+ #
389
+ def hostpart
390
+ self.class.parse_u32(hostpart_u32, 32)
391
+ end
380
392
 
381
393
  #
382
394
  # Returns a new IPv4 object with the
@@ -600,6 +612,18 @@ module IPAddress;
600
612
  def network_u32
601
613
  @u32 & @prefix.to_u32
602
614
  end
615
+
616
+ #
617
+ # Returns this address' host part in unsigned 32bits format
618
+ #
619
+ # ip = IPAddress("10.0.0.42/24")
620
+ #
621
+ # ip.host_u32
622
+ # #=> 42
623
+ #
624
+ def hostpart_u32
625
+ @u32 & ~@prefix.to_u32
626
+ end
603
627
 
604
628
  #
605
629
  # Returns the broadcast address in Unsigned 32bits format
@@ -616,7 +640,7 @@ module IPAddress;
616
640
  #
617
641
  # Checks whether a subnet includes the given IP address.
618
642
  #
619
- # Accepts an IPAddress::IPv4 object.
643
+ # Accepts an IPAddress::IPv4 object or a string.
620
644
  #
621
645
  # ip = IPAddress("192.168.10.100/24")
622
646
  #
@@ -628,13 +652,19 @@ module IPAddress;
628
652
  # ip.include? IPAddress("172.16.0.48/16")
629
653
  # #=> false
630
654
  #
655
+ # ip.include? "192.168.10.50"
656
+ # #=> true
657
+ #
631
658
  def include?(oth)
659
+ unless oth.is_a? IPAddress::IPv4
660
+ oth = IPv4.new(oth)
661
+ end
632
662
  @prefix <= oth.prefix and network_u32 == (oth.to_u32 & @prefix.to_u32)
633
663
  end
634
664
 
635
665
  #
636
666
  # Checks whether a subnet includes all the
637
- # given IPv4 objects.
667
+ # given IPv4 objects or strings.
638
668
  #
639
669
  # ip = IPAddress("192.168.10.100/24")
640
670
  #
@@ -644,6 +674,9 @@ module IPAddress;
644
674
  # ip.include_all?(addr1,addr2)
645
675
  # #=> true
646
676
  #
677
+ # ip.include_all?("192.168.10.102/24", "192.168.10.103/24")
678
+ # #=> true
679
+ #
647
680
  def include_all?(*others)
648
681
  others.all? {|oth| include?(oth)}
649
682
  end
@@ -886,6 +919,97 @@ module IPAddress;
886
919
  def +(oth)
887
920
  aggregate(*[self,oth].sort.map{|i| i.network})
888
921
  end
922
+
923
+ #
924
+ # Returns a new IPv4 object which is the result
925
+ # of advancing this IP address by a given value.
926
+ # In other words, this arithmetically adds IP addresses.
927
+ #
928
+ # Will raise an error if the resulting address is in a different subnet,
929
+ # except validating is set to false.
930
+ #
931
+ # Example:
932
+ #
933
+ # ip = IPAddress::IPv4.new("172.16.10.1/24")
934
+ # ip.add(5).to_string
935
+ # #=> "172.16.10.6/24"
936
+ def add(oth, validating=true)
937
+ oth = oth.to_i if oth.kind_of? IPAddress::IPv4 # oth shall be integer
938
+
939
+ new_obj = self.class.parse_u32(self.to_i + oth, prefix)
940
+
941
+ if validating and self.network_u32 != new_obj.network_u32
942
+ raise RuntimeError, "Subnet (/#{@prefix}) is not large enough."
943
+ end
944
+
945
+ new_obj
946
+ end
947
+
948
+ #
949
+ # Returns a new IPv4 object which is the result
950
+ # of decreasing this IP address by a given value.
951
+ # In other words, this arithmetically subtracts IP addresses.
952
+ #
953
+ # Will raise an error if the resulting address is in a different subnet,
954
+ # except validating is set to false.
955
+ #
956
+ # Example:
957
+ #
958
+ # ip = IPAddress::IPv4.new("172.16.10.10/24")
959
+ # ip.subtract(5).to_string
960
+ # #=> "172.16.10.5/24"
961
+ def subtract(oth, validating=true)
962
+ oth = oth.to_i if oth.kind_of? IPAddress::IPv4 # oth shall be integer
963
+ add(-oth, validating)
964
+ end
965
+
966
+ #
967
+ # Returns the network address of the n-th network succeeding this one.
968
+ #
969
+ # Example:
970
+ #
971
+ # ip = IPAddress::IPv4.new("172.16.10.0/24")
972
+ # ip.advance_network(24).to_string
973
+ # #=> "172.16.52.0/24"
974
+ def advance_network(amount)
975
+ IPAddress::IPv4.parse_u32(self.network.u32 + amount*self.size, @prefix)
976
+ end
977
+
978
+ #
979
+ # Returns the network address of the network succeeding this one.
980
+ #
981
+ # Example:
982
+ #
983
+ # ip = IPAddress::IPv4.new("172.16.10.0/24")
984
+ # ip.next_network.to_string
985
+ # #=> "172.16.11.0/24"
986
+ def next_network
987
+ advance_network 1
988
+ end
989
+
990
+ #
991
+ # Returns the network address of the n-th network preceeding this one.
992
+ #
993
+ # Example:
994
+ #
995
+ # ip = IPAddress::IPv4.new("172.16.10.0/24")
996
+ # ip.regress_network(5).to_string
997
+ # #=> "172.16.5.0/24"
998
+ def regress_network(amount)
999
+ advance_network(-amount)
1000
+ end
1001
+
1002
+ #
1003
+ # Returns the network address of the network preceeding this one.
1004
+ #
1005
+ # Example:
1006
+ #
1007
+ # ip = IPAddress::IPv4.new("172.16.10.0/24")
1008
+ # ip.previous_network.to_string
1009
+ # #=> "172.16.9.0/24"
1010
+ def previous_network
1011
+ regress_network 1
1012
+ end
889
1013
 
890
1014
  #
891
1015
  # Checks whether the ip address belongs to a
@@ -1164,7 +1288,9 @@ module IPAddress;
1164
1288
  return false if prefix == 0
1165
1289
  current_subnet = to_string
1166
1290
  self.prefix = @prefix - 1
1167
- (split.map{|i| i.to_string} - [current_subnet])[0]
1291
+ adjacent_subnet = (split.map{|i| i.to_string} - [current_subnet])[0]
1292
+ self.prefix = @prefix + 1
1293
+ return adjacent_subnet
1168
1294
  end
1169
1295
 
1170
1296
  #
@@ -246,6 +246,63 @@ module IPAddress;
246
246
  to_u128 | @prefix.to_u128 == @prefix.to_u128
247
247
  end
248
248
 
249
+ #
250
+ # Returns a new IPv6 object with the
251
+ # first host IP address in the range.
252
+ #
253
+ # Example: given the 2001:db8:8:800::/64 network, the first
254
+ # host IP address is 2001:db8:8:800::
255
+ #
256
+ # ip = IPAddress("2001:db8:8:800::/64")
257
+ #
258
+ # ip.first.to_s
259
+ # #=> "2001:db8:8:800::"
260
+ #
261
+ # The object IP doesn't need to be a network: the method
262
+ # automatically gets the network number from it
263
+ #
264
+ # ip = IPAddress("2001:db8:9:800::2/64")
265
+ #
266
+ # ip.first.to_s
267
+ # #=> "2001:db8:9:800::"
268
+ #
269
+ def first
270
+ if prefix == 128
271
+ return self
272
+ else
273
+ IPAddress::IPv6::parse_u128(network_u128)
274
+ end
275
+ end
276
+
277
+ #
278
+ # Like its sibling method IPv4#first, this method
279
+ # returns a new IPv4 object with the
280
+ # last host IP address in the range.
281
+ #
282
+ # Example: given the 192.168.100.0/24 network, the last
283
+ # host IP address is 192.168.100.254
284
+ #
285
+ # ip = IPAddress("2001:db8:8:800::/64")
286
+ #
287
+ # ip.last.to_s
288
+ # #=> "2001:db8:8:800:ffff:ffff:ffff:ffff"
289
+ #
290
+ # The object IP doesn't need to be a network: the method
291
+ # automatically gets the network number from it
292
+ #
293
+ # ip = IPAddress("2001:db8:9:800::2/64")
294
+ #
295
+ # ip.last.to_s
296
+ # #=> "2001:db8:9:800:ffff:ffff:ffff:ffff"
297
+ #
298
+ def last
299
+ if prefix == 128
300
+ return self
301
+ else
302
+ IPAddress::IPv6::parse_u128(broadcast_u128)
303
+ end
304
+ end
305
+
249
306
  #
250
307
  # Returns the 16-bits value specified by index
251
308
  #
@@ -337,8 +394,110 @@ module IPAddress;
337
394
  to_hex.reverse.gsub(/./){|c| c+"."} + "ip6.arpa"
338
395
  end
339
396
  alias_method :arpa, :reverse
397
+
398
+ #
399
+ # Returns a new IPv6 object which is the result
400
+ # of advancing this IP address by a given value.
401
+ # In other words, this arithmetically adds IP addresses.
402
+ #
403
+ # Will raise an error if the resulting address is in a different subnet,
404
+ # except validating is set to false.
405
+ #
406
+ # Example:
407
+ #
408
+ # ip = IPAddress::IPv6.new("fc42:1337::/64")
409
+ # ip.add(5).to_string
410
+ # #=> "fc42:1337::5/64"
411
+ def add(oth, validating=true)
412
+ oth = oth.to_i if oth.kind_of? IPAddress::IPv6 # oth shall be integer
413
+
414
+ new_obj = self.class.parse_u128(self.to_i + oth, prefix)
415
+
416
+ if validating and self.network_u128 != new_obj.network_u128
417
+ raise RuntimeError, "Subnet (/#{@prefix}) is not large enough."
418
+ end
419
+
420
+ new_obj
421
+ end
422
+
423
+ #
424
+ # Returns a new IPv6 object which is the result
425
+ # of decreasing this IP address by a given value.
426
+ # In other words, this arithmetically subtracts IP addresses.
427
+ #
428
+ # Will raise an error if the resulting address is in a different subnet,
429
+ # except validating is set to false.
430
+ #
431
+ # Example:
432
+ #
433
+ # ip = IPAddress::IPv6.new("fc42:1337::a/64")
434
+ # ip.subtract(5).to_string
435
+ # #=> "fc42:1337::5/64"
436
+ def subtract(oth, validating=true)
437
+ oth = oth.to_i if oth.kind_of? IPAddress::IPv6 # oth shall be integer
438
+ add(-oth, validating)
439
+ end
340
440
 
341
441
  #
442
+ # Returns the network address of the n-th network succeeding this one.
443
+ #
444
+ # Example:
445
+ #
446
+ # ip = IPAddress::IPv6.new("fc42:1337:0:0::/64")
447
+ # ip.advance_network(5).to_string
448
+ # #=> "fc42:1337:0:5::/64"
449
+ def advance_network(amount)
450
+ IPAddress::IPv6.parse_u128(self.network.to_i + amount*self.size, @prefix)
451
+ end
452
+
453
+ #
454
+ # Returns the network address of the network succeeding this one.
455
+ #
456
+ # Example:
457
+ #
458
+ # ip = IPAddress::IPv6.new("fc42:1337:0:0::/64")
459
+ # ip.next_network.to_string
460
+ # #=> "fc42:1337:0:1::/64"
461
+ def next_network
462
+ advance_network 1
463
+ end
464
+
465
+ #
466
+ # Returns the network address of the n-th network preceeding this one.
467
+ #
468
+ # Example:
469
+ #
470
+ # ip = IPAddress::IPv6.new("fc42:1337:0:5::/64")
471
+ # ip.regress_network(4).to_string
472
+ # #=> "fc42:1337:0:1::/64"
473
+ def regress_network(amount)
474
+ advance_network(-amount)
475
+ end
476
+
477
+ #
478
+ # Returns the network address of the network preceeding this one.
479
+ #
480
+ # Example:
481
+ #
482
+ # ip = IPAddress::IPv6.new("fc42:1337:0:5::/64")
483
+ # ip.previous_network.to_string
484
+ # #=> "fc42:1337:0:4::/64"
485
+ def previous_network
486
+ regress_network 1
487
+ end
488
+
489
+ #
490
+ # Returns a new IPv6 object containing only the host part of this IP.
491
+ #
492
+ # ip = IPAddress::IPv6.new("fc42:1337:0:5::7/64")
493
+ #
494
+ # ip.hostpart.to_s
495
+ # #=> "::7"
496
+ #
497
+ def hostpart
498
+ self.class.parse_u128(hostpart_u128, 128)
499
+ end
500
+
342
501
  # Splits a network into different subnets
343
502
  #
344
503
  # NOTE: Will allow you to split past /64 against RFC 5375
@@ -396,6 +555,18 @@ module IPAddress;
396
555
  def network_u128
397
556
  to_u128 & @prefix.to_u128
398
557
  end
558
+
559
+ #
560
+ # Returns this address' host part in unsigned 128bits format
561
+ #
562
+ # ip = IPAddress::IPv6.new("fc42:1337:0:5::7/64")
563
+ #
564
+ # ip.host_u128
565
+ # #=> 7
566
+ #
567
+ def hostpart_u128
568
+ to_u128 & ~@prefix.to_u128
569
+ end
399
570
 
400
571
  #
401
572
  # Returns the broadcast address in Unsigned 128bits format
@@ -441,13 +612,19 @@ module IPAddress;
441
612
  # ip6.include? IPAddress("2001:db8:1::8:800:200c:417a/76")
442
613
  # #=> false
443
614
  #
615
+ # ip6.include? "2001:db8::8:800:200c:1"
616
+ # #=> true
617
+ #
444
618
  def include?(oth)
619
+ unless oth.is_a? IPAddress::IPv6
620
+ oth = IPv6.new(oth)
621
+ end
445
622
  @prefix <= oth.prefix and network_u128 == self.class.new(oth.address+"/#@prefix").network_u128
446
623
  end
447
624
 
448
625
  #
449
626
  # Checks whether a subnet includes all the
450
- # given IPv4 objects.
627
+ # given IPv4 objects or strings.
451
628
  #
452
629
  # ip = IPAddress("2001:db8:8:800::1/64")
453
630
  #
@@ -457,6 +634,9 @@ module IPAddress;
457
634
  # ip.include_all?(addr1,addr2)
458
635
  # #=> true
459
636
  #
637
+ # ip.include_all?("2001:db8:8:800::2/64", "2001:db8:8:800::8/64")
638
+ # #=> true
639
+ #
460
640
  def include_all?(*others)
461
641
  others.all? {|oth| include?(oth)}
462
642
  end
@@ -771,6 +951,23 @@ module IPAddress;
771
951
  self.class.parse_u128(network_u128, @prefix)
772
952
  end
773
953
 
954
+ #
955
+ # Returns the broadcast address for the given IP.
956
+ # As this is IPv6 it is just the last IP
957
+ #
958
+ # ip = IPAddress("2001:db8:8:800::/64")
959
+ #
960
+ # ip.broadcast.to_s
961
+ # #=> "2001:db8:8:800::"
962
+ #
963
+ def broadcast
964
+ if prefix == 128
965
+ return self
966
+ else
967
+ IPAddress::IPv6::parse_u128(broadcast_u128)
968
+ end
969
+ end
970
+
774
971
  #
775
972
  # Extract 16 bits groups from a string
776
973
  #
@@ -915,9 +1112,10 @@ module IPAddress;
915
1112
  def self.summarize(*args)
916
1113
  # one network? no need to summarize
917
1114
  return [args.first.network] if args.size == 1
1115
+ args_size = args.size
918
1116
 
919
1117
  i = 0
920
- result = args.dup.sort.map{|ip| ip.network}
1118
+ result = args.sort.map{|ip| ip.network}
921
1119
  while i < result.size-1
922
1120
  sum = result[i] + result[i+1]
923
1121
  result[i..i+1] = sum.first if sum.size == 1
@@ -925,7 +1123,7 @@ module IPAddress;
925
1123
  end
926
1124
 
927
1125
  result.flatten!
928
- if result.size == args.size
1126
+ if result.size == args_size
929
1127
  # nothing more to summarize
930
1128
  return result
931
1129
  else
@@ -977,7 +1175,9 @@ module IPAddress;
977
1175
  return false if prefix == 0
978
1176
  current_subnet = to_string
979
1177
  self.prefix = @prefix - 1
980
- (split.map{|i| i.to_string} - [current_subnet])[0]
1178
+ adjacent_subnet = (split.map{|i| i.to_string} - [current_subnet])[0]
1179
+ self.prefix = @prefix + 1
1180
+ return adjacent_subnet
981
1181
  end
982
1182
 
983
1183
  private
@@ -1,3 +1,3 @@
1
1
  module IPAddress
2
- VERSION = "0.11.0"
2
+ VERSION = "0.14.0"
3
3
  end
@@ -327,7 +327,10 @@ class IPv4Test < Minitest::Test
327
327
  assert_equal false, ip.include?(@klass.new("5.5.5.5/32"))
328
328
  assert_equal false, ip.include?(@klass.new("11.0.0.0/8"))
329
329
  ip = @klass.new("13.13.0.0/13")
330
- assert_equal false, ip.include?(@klass.new("13.16.0.0/32"))
330
+ assert_equal false, ip.include?(@klass.new("13.16.0.0/32"))
331
+ ip = @klass.new("10.10.10.0/24")
332
+ assert_equal true, ip.include?("10.10.10.100")
333
+ assert_equal false, ip.include?("10.10.9.100")
331
334
  end
332
335
 
333
336
  def test_method_include_all?
@@ -336,6 +339,8 @@ class IPv4Test < Minitest::Test
336
339
  addr2 = @klass.new("192.168.10.103/24")
337
340
  assert_equal true, ip.include_all?(addr1,addr2)
338
341
  assert_equal false, ip.include_all?(addr1, @klass.new("13.16.0.0/32"))
342
+ assert_equal true, ip.include_all?("192.168.10.102/24", "192.168.10.103/24")
343
+ assert_equal false, ip.include_all?(addr1, "13.16.0.0/32")
339
344
  end
340
345
 
341
346
  def test_method_ipv4?
@@ -455,7 +460,7 @@ class IPv4Test < Minitest::Test
455
460
 
456
461
  ip2 = @klass.new("172.16.12.2/24")
457
462
  assert_equal [ip1.network.to_string, ip2.network.to_string],
458
- (ip1 + ip2).map{|i| i.to_string}
463
+ (ip1 + ip2).map{|i| i.to_string}
459
464
 
460
465
  ip1 = @klass.new("10.0.0.0/23")
461
466
  ip2 = @klass.new("10.0.2.0/24")
@@ -533,6 +538,57 @@ class IPv4Test < Minitest::Test
533
538
  assert_equal "172.16.8.0/22", @ip.supernet(22).to_string
534
539
  end
535
540
 
541
+ def test_method_add
542
+ ip = IPAddress::IPv4.new("172.16.10.1/24")
543
+ assert_equal ip.add(5), IPAddress::IPv4.new("172.16.10.6/24")
544
+ assert_equal ip.add(IPAddress::IPv4.new("0.0.0.5/6")), IPAddress::IPv4.new("172.16.10.6/24")
545
+ assert_equal ip.add(50), IPAddress::IPv4.new("172.16.10.51/24")
546
+ assert_equal ip.add(254), IPAddress::IPv4.new("172.16.10.255/24")
547
+ assert_raises(RuntimeError) {ip.add(255)}
548
+ assert_equal ip.add(255, false), IPAddress::IPv4.new("172.16.11.0/24")
549
+ assert_raises(RuntimeError) {ip.add(1000)}
550
+ ip = IPAddress::IPv4.new("172.16.10.1/30")
551
+ assert_equal ip.add(2), IPAddress::IPv4.new("172.16.10.3/30")
552
+ assert_raises(RuntimeError) {ip.add(3)}
553
+ end
554
+
555
+ def test_method_subtract
556
+ ip = IPAddress::IPv4.new("172.16.10.10/24")
557
+ assert_equal ip.subtract(5), IPAddress::IPv4.new("172.16.10.5/24")
558
+ assert_equal ip.subtract(IPAddress::IPv4.new("0.0.0.5/32")), IPAddress::IPv4.new("172.16.10.5/24")
559
+ assert_equal ip.subtract(10), IPAddress::IPv4.new("172.16.10.0/24")
560
+ assert_raises(RuntimeError) {ip.subtract(11)}
561
+ assert_equal ip.subtract(11, false), IPAddress::IPv4.new("172.16.9.255/24")
562
+ assert_raises(RuntimeError) {ip.subtract(IPAddress::IPv4.new("0.0.0.11/16"))}
563
+ end
564
+
565
+ def test_method_hostpart
566
+ ip = IPAddress::IPv4.new("172.16.10.64/24")
567
+ assert_equal ip.hostpart.to_s, "0.0.0.64"
568
+ ip = IPAddress::IPv4.new("172.16.10.130/25")
569
+ assert_equal ip.hostpart.to_s, "0.0.0.2"
570
+ end
571
+
572
+ def test_method_advance_network
573
+ ip = IPAddress::IPv4.new("172.16.10.64/24")
574
+ assert_equal ip.advance_network(42), IPAddress::IPv4.new("172.16.52.0/24")
575
+ end
576
+
577
+ def test_method_next_network
578
+ ip = IPAddress::IPv4.new("172.16.10.64/24")
579
+ assert_equal ip.next_network, IPAddress::IPv4.new("172.16.11.0/24")
580
+ end
581
+
582
+ def test_method_regress_network
583
+ ip = IPAddress::IPv4.new("172.16.10.64/24")
584
+ assert_equal ip.regress_network(5), IPAddress::IPv4.new("172.16.5.0/24")
585
+ end
586
+
587
+ def test_method_previous_network
588
+ ip = IPAddress::IPv4.new("172.16.10.64/24")
589
+ assert_equal ip.previous_network, IPAddress::IPv4.new("172.16.9.0/24")
590
+ end
591
+
536
592
  def test_classmethod_parse_u32
537
593
  @decimal_values.each do |addr,int|
538
594
  ip = @klass.parse_u32(int)
@@ -689,6 +745,7 @@ class IPv4Test < Minitest::Test
689
745
  def test_finds_adjacent_subnet
690
746
  ip = @klass.new("10.0.0.0/24")
691
747
  assert_equal "10.0.1.0/24", ip.find_adjacent_subnet
748
+ assert_equal 24, ip.prefix
692
749
  refute @klass.new("10.0.0.0/0").find_adjacent_subnet
693
750
  assert_equal "10.0.0.0/8", @klass.new("11.0.0.0/8").find_adjacent_subnet
694
751
  assert_equal "172.16.0.0/16", @klass.new("172.17.0.0/16").find_adjacent_subnet
@@ -128,6 +128,36 @@ class IPv6Test < Minitest::Test
128
128
  assert_equal bits, @ip.bits
129
129
  end
130
130
 
131
+ def test_method_first
132
+ ip = @klass.new("2001:db8:8:800::/64")
133
+ assert_instance_of @klass, ip.first
134
+ assert_equal "2001:db8:8:800::", ip.first.to_s
135
+ ip = @klass.new("2001:db8:8::/48")
136
+ assert_instance_of @klass, ip.first
137
+ assert_equal "2001:db8:8::", ip.first.to_s
138
+ ip = @klass.new("2001:db8::/32")
139
+ assert_instance_of @klass, ip.first
140
+ assert_equal "2001:db8::", ip.first.to_s
141
+ ip = @klass.new("2001:db8::8:800:200c:417a/64")
142
+ assert_instance_of @klass, ip.first
143
+ assert_equal "2001:db8::", ip.first.to_s
144
+ end
145
+
146
+ def test_method_last
147
+ ip = @klass.new("2001:db8:8:800::/64")
148
+ assert_instance_of @klass, ip.last
149
+ assert_equal "2001:db8:8:800:ffff:ffff:ffff:ffff", ip.last.to_s
150
+ ip = @klass.new("2001:db8:8::/48")
151
+ assert_instance_of @klass, ip.last
152
+ assert_equal "2001:db8:8:ffff:ffff:ffff:ffff:ffff", ip.last.to_s
153
+ ip = @klass.new("2001:db8::/32")
154
+ assert_instance_of @klass, ip.last
155
+ assert_equal "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff", ip.last.to_s
156
+ ip = @klass.new("2001:db8::8:800:200c:417a/64")
157
+ assert_instance_of @klass, ip.last
158
+ assert_equal "2001:db8::ffff:ffff:ffff:ffff", ip.last.to_s
159
+ end
160
+
131
161
  def test_method_prefix=()
132
162
  ip = @klass.new "2001:db8::8:800:200c:417a"
133
163
  assert_equal 128, ip.prefix
@@ -322,6 +352,9 @@ class IPv6Test < Minitest::Test
322
352
  not_included = @klass.new "2001:db8:1::8:800:200c:417a/76"
323
353
  assert_equal true, @ip.include?(included)
324
354
  assert_equal false, @ip.include?(not_included)
355
+ # string test
356
+ assert_equal true, @ip.include?("2001:db8::8:800:200c:2")
357
+ assert_equal false, @ip.include?("2001:db8:1::8:800:200c:417a")
325
358
  end
326
359
 
327
360
  def test_method_include_all?
@@ -330,6 +363,8 @@ class IPv6Test < Minitest::Test
330
363
  addr2 = @klass.new("2001:db8:8:800::8/64")
331
364
  assert_equal true, ip.include_all?(addr1,addr2)
332
365
  assert_equal false, ip.include_all?(addr1, @klass.new("2002:db8:8:800::2/64"))
366
+ assert_equal true, ip.include_all?("2001:db8:8:800::2/64", "2001:db8:8:800::8/64")
367
+ assert_equal false, ip.include_all?(addr1, "2002:db8:8:800::2/64")
333
368
  end
334
369
 
335
370
  def test_method_to_hex
@@ -399,6 +434,21 @@ class IPv6Test < Minitest::Test
399
434
  end
400
435
  end
401
436
 
437
+ def test_method_broadcast
438
+ ip = @klass.new("2001:db8:8:800::/64")
439
+ assert_instance_of @klass, ip.broadcast
440
+ assert_equal "2001:db8:8:800:ffff:ffff:ffff:ffff", ip.broadcast.to_s
441
+ ip = @klass.new("2001:db8:8::/48")
442
+ assert_instance_of @klass, ip.broadcast
443
+ assert_equal "2001:db8:8:ffff:ffff:ffff:ffff:ffff", ip.broadcast.to_s
444
+ ip = @klass.new("2001:db8::/32")
445
+ assert_instance_of @klass, ip.broadcast
446
+ assert_equal "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff", ip.broadcast.to_s
447
+ ip = @klass.new("2001:db8::8:800:200c:417a/64")
448
+ assert_instance_of @klass, ip.broadcast
449
+ assert_equal "2001:db8::ffff:ffff:ffff:ffff", ip.broadcast.to_s
450
+ end
451
+
402
452
  def test_method_network
403
453
  @networks.each do |addr,net|
404
454
  ip = @klass.new addr
@@ -572,13 +622,61 @@ class IPv6Test < Minitest::Test
572
622
 
573
623
  def test_finds_adjacent_subnet
574
624
  refute @klass.new("::/0").find_adjacent_subnet
625
+
626
+ ip = @klass.new("2001:db8::/32")
627
+ assert_equal "2001:db9::/32", ip.find_adjacent_subnet
628
+ assert_equal 32, ip.prefix
629
+
575
630
  assert_equal "2001:db9::/32", @klass.new("2001:db8::/32").find_adjacent_subnet
576
631
  assert_equal "2001:db8:0:1::/64", @klass.new("2001:db8::/64").find_adjacent_subnet
577
632
  assert_equal "2001:db8:8:2000::/51", @klass.new("2001:db8:8::/51").find_adjacent_subnet
578
- # assert_equal "", @klass.new("").find_adjacent_subnet
579
- # assert_equal "", @klass.new("").find_adjacent_subnet
580
633
  end
581
634
 
635
+ def test_method_add
636
+ ip = IPAddress::IPv6.new("fc42:1337::/64")
637
+ assert_equal ip.add(5), IPAddress::IPv6.new("fc42:1337::5/64")
638
+ assert_equal ip.add(IPAddress::IPv6.new("::5/42")), IPAddress::IPv6.new("fc42:1337::5/64")
639
+ assert_equal ip.add(50), IPAddress::IPv6.new("fc42:1337::32/64")
640
+ ip = IPAddress::IPv6.new("fc42:1337::/120")
641
+ assert_equal ip.add(2), IPAddress::IPv6.new("fc42:1337::2/120")
642
+ assert_raises(RuntimeError) {ip.add(256)}
643
+ assert_equal ip.add(256, false), IPAddress::IPv6.new("fc42:1337::100/120")
644
+ end
645
+
646
+ def test_method_subtract
647
+ ip = IPAddress::IPv6.new("fc42:1337::5/64")
648
+ assert_equal ip.subtract(5), IPAddress::IPv6.new("fc42:1337::/64")
649
+ assert_equal ip.subtract(IPAddress::IPv6.new("::5/12")), IPAddress::IPv6.new("fc42:1337::0/64")
650
+ assert_raises(RuntimeError) {ip.subtract(11)}
651
+ assert_raises(RuntimeError) {ip.subtract(IPAddress::IPv6.new("::11/66"))}
652
+ end
653
+
654
+ def test_method_hostpart
655
+ ip = IPAddress::IPv6.new("fc42:1337:0:5::7/64")
656
+ assert_equal ip.hostpart.to_s, "::7"
657
+ end
658
+
659
+ def test_method_advance_network
660
+ ip = IPAddress::IPv6.new("fc42:1337:0:0::/64")
661
+ assert_equal ip.advance_network(5), IPAddress::IPv6.new("fc42:1337:0:5::/64")
662
+ end
663
+
664
+ def test_method_next_network
665
+ ip = IPAddress::IPv6.new("fc42:1337:0:0::/64")
666
+ assert_equal ip.next_network, IPAddress::IPv6.new("fc42:1337:0:1::/64")
667
+ end
668
+
669
+ def test_method_regress_network
670
+ ip = IPAddress::IPv6.new("fc42:1337:0:5::/64")
671
+ assert_equal ip.regress_network(4), IPAddress::IPv6.new("fc42:1337:0:1::/64")
672
+ end
673
+
674
+ def test_method_previous_network
675
+ ip = IPAddress::IPv6.new("fc42:1337:0:5::/64")
676
+ assert_equal ip.previous_network, IPAddress::IPv6.new("fc42:1337:0:4::/64")
677
+ end
678
+
679
+
582
680
  end # class IPv6Test
583
681
 
584
682
  class IPv6UnspecifiedTest < Minitest::Test
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ipaddress_2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bluemonk
8
8
  - mikemackintosh
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-01-22 00:00:00.000000000 Z
12
+ date: 2021-07-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -131,7 +131,7 @@ dependencies:
131
131
  version: '0'
132
132
  description: |-
133
133
  IPAddress2 is a Ruby library designed to make manipulation
134
- of IPv4 and IPv6 addresses both powerful and simple. It mantains
134
+ of IPv4 and IPv6 addresses both powerful and simple. It maintains
135
135
  a layer of compatibility with Ruby's own IPAddr, while
136
136
  addressing many of its issues.
137
137
  email: adam@21eleven.com
@@ -168,11 +168,11 @@ files:
168
168
  - test/ipaddress_2/prefix_test.rb
169
169
  - test/ipaddress_2_test.rb
170
170
  - test/test_helper.rb
171
- homepage: https://github.com/ipaddress2-gem/ipaddress2
171
+ homepage: https://github.com/ipaddress2-gem/ipaddress_2
172
172
  licenses:
173
173
  - MIT
174
174
  metadata: {}
175
- post_install_message:
175
+ post_install_message:
176
176
  rdoc_options: []
177
177
  require_paths:
178
178
  - lib
@@ -187,9 +187,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
187
  - !ruby/object:Gem::Version
188
188
  version: '0'
189
189
  requirements: []
190
- rubyforge_project:
191
- rubygems_version: 2.7.8
192
- signing_key:
190
+ rubygems_version: 3.2.3
191
+ signing_key:
193
192
  specification_version: 4
194
193
  summary: IPv4/IPv6 address manipulation library
195
194
  test_files: []