iplogic 0.2.0 → 0.2.1
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.
- data/README.md +3 -3
- data/Rakefile +14 -11
- data/iplogic.gemspec +3 -6
- data/lib/iplogic.rb +1 -1
- data/lib/iplogic/ip.rb +66 -31
- data/spec/cidr_spec.rb +55 -94
- data/spec/ip_spec.rb +42 -41
- data/spec/radix_spec.rb +2 -4
- data/spec/spec_helper.rb +4 -7
- metadata +6 -16
data/README.md
CHANGED
@@ -5,7 +5,7 @@ Usage:
|
|
5
5
|
require 'iplogic'
|
6
6
|
include IPLogic
|
7
7
|
|
8
|
-
ip = IP
|
9
|
-
cidr = CIDR
|
8
|
+
ip = IP['11.22.33.44']
|
9
|
+
cidr = CIDR['11.22.32.00/20']
|
10
10
|
|
11
|
-
Look in `spec/ip_spec.rb` and `spec/cidr_spec.rb` for a neat summary of
|
11
|
+
Look in `spec/ip_spec.rb` and `spec/cidr_spec.rb` for a neat summary of all the methods available.
|
data/Rakefile
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/testtask'
|
3
3
|
|
4
|
-
# begin
|
5
4
|
task :spec do
|
6
|
-
sh "rspec -I spec/ spec/*_spec.rb"
|
5
|
+
sh "bundle exec rspec -I spec/ spec/*_spec.rb"
|
7
6
|
end
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
task :doc do
|
9
|
+
sh "bundle exec yard"
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => [:spec]
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
CLEAN = %w(
|
15
|
+
*.gem
|
16
|
+
**/*.rbc
|
17
|
+
).map(&Dir.method(:glob)).flatten
|
18
|
+
|
19
|
+
task :clean do
|
20
|
+
sh "rm -f", *CLEAN
|
21
|
+
end
|
data/iplogic.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.version = IPLogic::VERSION
|
6
6
|
|
7
7
|
s.authors = ["Jay Adkisson"]
|
8
|
-
s.date =
|
8
|
+
s.date = Date.today
|
9
9
|
s.description = <<-desc.strip
|
10
10
|
An IPv4 swiss-army chainsaw
|
11
11
|
desc
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
Because it's just a 32-bit integer.
|
15
15
|
sum
|
16
16
|
|
17
|
-
s.email = %q{
|
17
|
+
s.email = %q{jjmadkisson@gmail.com}
|
18
18
|
s.extra_rdoc_files = %w(
|
19
19
|
LICENSE
|
20
20
|
README.md
|
@@ -32,9 +32,8 @@ Gem::Specification.new do |s|
|
|
32
32
|
lib/iplogic/ip.rb
|
33
33
|
)
|
34
34
|
|
35
|
-
s.homepage = 'http://github.com/
|
35
|
+
s.homepage = 'http://github.com/jayferd/iplogic'
|
36
36
|
s.require_paths = ["lib"]
|
37
|
-
s.rubygems_version = '1.3.7'
|
38
37
|
|
39
38
|
s.test_files = %w(
|
40
39
|
spec/ip_spec.rb
|
@@ -42,7 +41,5 @@ Gem::Specification.new do |s|
|
|
42
41
|
spec/spec_helper.rb
|
43
42
|
spec/radix_spec.rb
|
44
43
|
)
|
45
|
-
|
46
|
-
s.add_development_dependency('rspec', '~> 1.0')
|
47
44
|
end
|
48
45
|
|
data/lib/iplogic.rb
CHANGED
data/lib/iplogic/ip.rb
CHANGED
@@ -1,34 +1,34 @@
|
|
1
1
|
module IPLogic
|
2
2
|
class IP
|
3
3
|
class << self
|
4
|
-
# Basic
|
4
|
+
# Basic idempotent wrapper for creating addresses.
|
5
5
|
#
|
6
|
-
#
|
6
|
+
# @param [String, Fixnum, Array, nil]
|
7
|
+
# @return [IP] the wrapped IP address
|
7
8
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
9
|
+
# @example
|
10
|
+
# >> IP['11.22.33.44']
|
11
|
+
# => #<IP [ 11.22.33.44 ]>
|
11
12
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# @example
|
14
|
+
# >> IP[0xFFFFFFFF]
|
15
|
+
# => #<IP [ 255.255.255.255 ]>
|
15
16
|
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
17
|
+
# @example
|
18
|
+
# >> IP[nil]
|
19
|
+
# => #<IP [ 0.0.0.0 ]>
|
19
20
|
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
21
|
+
# @example
|
22
|
+
# >> IP(['11', 22, 33, '44'])
|
23
|
+
# => #<IP [ 11.22.33.44 ]>
|
23
24
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
25
|
+
# @example
|
26
|
+
# >> ip = IP['11.22.33.44']
|
27
|
+
# => #<IP [ 11.22.33.44 ]>
|
28
|
+
# >> IP(ip)
|
29
|
+
# => #<IP [ 11.22.33.44 ]>
|
30
|
+
# >> ip.object_id == IP[ip].object_id
|
31
|
+
# => true
|
32
32
|
def wrap(arg)
|
33
33
|
return arg if arg.is_a? IP
|
34
34
|
|
@@ -56,9 +56,11 @@ module IPLogic
|
|
56
56
|
|
57
57
|
FormatError = Class.new(ArgumentError)
|
58
58
|
|
59
|
-
#
|
60
|
-
|
61
|
-
|
59
|
+
# @return [IP] a random IP address. Useful for mocks / tests
|
60
|
+
# @param [CIDR] cidr an optional CIDR-like object to limit the IP to
|
61
|
+
def rand(cidr=CIDR.all)
|
62
|
+
cidr = CIDR.wrap(cidr)
|
63
|
+
cidr.min + Kernel.rand(cidr.size)
|
62
64
|
end
|
63
65
|
|
64
66
|
private
|
@@ -72,20 +74,29 @@ module IPLogic
|
|
72
74
|
end
|
73
75
|
|
74
76
|
# -*- instance methods -*-
|
77
|
+
|
78
|
+
# Get the integer representation of this IP address
|
79
|
+
# @return [Integer]
|
75
80
|
attr_reader :int
|
76
81
|
alias to_i int
|
82
|
+
|
83
|
+
# an IP can be used anywhere an integer can
|
77
84
|
alias to_int int
|
78
85
|
|
79
86
|
def initialize(int, extra={})
|
80
87
|
@int = int
|
81
88
|
end
|
82
89
|
|
83
|
-
|
84
|
-
|
90
|
+
MAXIP = IP.new(0xFFFFFFFF)
|
91
|
+
# @return [IP] The maximum IP address: 255.255.255.255
|
85
92
|
def self.max
|
86
93
|
MAXIP
|
87
94
|
end
|
88
95
|
|
96
|
+
# @return [Array] an array of the four octets.
|
97
|
+
#
|
98
|
+
# @example
|
99
|
+
# IP['1.2.3.4'].octets # => [1, 2, 3, 4]
|
89
100
|
def octets
|
90
101
|
@octets ||= begin
|
91
102
|
rad = int.radix(256)
|
@@ -94,6 +105,7 @@ module IPLogic
|
|
94
105
|
end
|
95
106
|
alias parts octets
|
96
107
|
|
108
|
+
# @return [String] the usual string representation of the ip address.
|
97
109
|
def to_s
|
98
110
|
octets.join('.')
|
99
111
|
end
|
@@ -102,6 +114,8 @@ module IPLogic
|
|
102
114
|
"#<IP [ #{self} ]>"
|
103
115
|
end
|
104
116
|
|
117
|
+
# an IP uses its string representation as its hash
|
118
|
+
# @return [String]
|
105
119
|
def hash
|
106
120
|
self.to_s.hash
|
107
121
|
end
|
@@ -112,23 +126,35 @@ module IPLogic
|
|
112
126
|
alias == eql?
|
113
127
|
|
114
128
|
include Comparable
|
129
|
+
# IP addresses are ordered in the usual way
|
115
130
|
def <=>(other)
|
116
131
|
self.int <=> other.int
|
117
132
|
end
|
118
133
|
|
134
|
+
# @param [#to_i] int_ish the amount to add
|
135
|
+
# @return [IP] the result of adding int_ish to the underlying integer
|
119
136
|
def +(int_ish)
|
120
137
|
IP.wrap(int + int_ish.to_i)
|
121
138
|
end
|
122
139
|
|
140
|
+
# @param [#to_i] int_ish the amount to subtract
|
141
|
+
# @return [IP] the result of subtracting int_ish from the underlying integer
|
142
|
+
def -(int_ish)
|
143
|
+
self + (-int_ish.to_i)
|
144
|
+
end
|
145
|
+
|
123
146
|
# This allows IP "ranges" with (ip1..ip2)
|
147
|
+
# @return [IP]
|
124
148
|
def succ
|
125
149
|
self + 1
|
126
150
|
end
|
127
151
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
152
|
+
# given a netmask, returns the network prefix.
|
153
|
+
#
|
154
|
+
# @return [IP] the network prefix
|
155
|
+
#
|
156
|
+
# @example
|
157
|
+
# IP['1.2.3.4'].prefix('255.255.0.0') # => #<IP [ 1.2.0.0 ]>
|
132
158
|
def prefix(netmask)
|
133
159
|
CIDR.wrap(self, netmask).min
|
134
160
|
end
|
@@ -138,11 +164,19 @@ module IPLogic
|
|
138
164
|
CIDR.wrap(self, netmask).max
|
139
165
|
end
|
140
166
|
|
167
|
+
# given a netmask, returns the "rest field" - the bits
|
168
|
+
# not covered by the netmask. See CIDR#rest_field.
|
169
|
+
#
|
170
|
+
# IP['1.2.3.4'].rest_field # => #<IP [ 0.0.3.4 ]>
|
171
|
+
#
|
172
|
+
# @return [IP] the rest field
|
173
|
+
# @see CIDR#rest_field
|
141
174
|
def rest_field(netmask)
|
142
175
|
CIDR.wrap(self, netmask).rest_field
|
143
176
|
end
|
144
177
|
alias rest rest_field
|
145
178
|
|
179
|
+
# test if this IP address is a valid netmask.
|
146
180
|
def netmask?
|
147
181
|
maxint32 = 0xFFFFFFFF
|
148
182
|
(0..32).any? do |i|
|
@@ -150,6 +184,7 @@ module IPLogic
|
|
150
184
|
end
|
151
185
|
end
|
152
186
|
|
187
|
+
# raises an error unless this IP address is a valid netmask.
|
153
188
|
def assert_netmask!
|
154
189
|
raise ArgumentError, <<-msg.strip unless netmask?
|
155
190
|
#{self.inspect} is not a valid netmask.
|
data/spec/cidr_spec.rb
CHANGED
@@ -1,161 +1,122 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
1
|
describe CIDR do
|
4
2
|
it "parses an IP-ish and netmask-ish" do
|
5
3
|
r = CIDR['4.33.222.111', '255.255.240.0']
|
6
|
-
r.
|
7
|
-
r.inspect.
|
4
|
+
assert { r.is_a? CIDR }
|
5
|
+
assert { r.inspect.include? '4.33.222.111/20' }
|
8
6
|
|
9
7
|
r = CIDR[IP['4.33.222.111'], 20]
|
10
|
-
r.
|
11
|
-
r.inspect.
|
8
|
+
assert { r.is_a? CIDR }
|
9
|
+
assert { r.inspect.include? '4.33.222.111/20' }
|
12
10
|
|
13
11
|
r = CIDR['4.33.222.111', IP['255.255.240.0']]
|
14
|
-
r.
|
15
|
-
r.inspect.
|
12
|
+
assert { r.is_a? CIDR }
|
13
|
+
assert { r.inspect.include? '4.33.222.111/20' }
|
16
14
|
end
|
17
15
|
|
18
16
|
it "parses slash notation" do
|
19
17
|
r = CIDR['11.22.33.44/8']
|
20
|
-
r.
|
21
|
-
r.inspect.
|
18
|
+
assert { r.is_a? CIDR }
|
19
|
+
assert { r.inspect.include? '11.22.33.44/8' }
|
22
20
|
end
|
23
21
|
|
24
22
|
it "parses slash notation with a netmask" do
|
25
23
|
r = CIDR['11.22.33.44/255.255.255.0']
|
26
|
-
r.ip.
|
27
|
-
r.ip.to_s
|
28
|
-
r.bits
|
29
|
-
r.netmask
|
24
|
+
assert { r.ip.is_a? IP }
|
25
|
+
assert { r.ip.to_s == '11.22.33.44' }
|
26
|
+
assert { r.bits == 24 }
|
27
|
+
assert { r.netmask == '255.255.255.0' }
|
30
28
|
end
|
31
29
|
|
32
30
|
it "parses shortened slash notation" do
|
33
31
|
r = CIDR['11.22.33/24']
|
34
|
-
r.ip.
|
35
|
-
r.ip.to_s
|
36
|
-
r.bits
|
37
|
-
r.netmask
|
32
|
+
assert { r.ip.is_a? IP }
|
33
|
+
assert { r.ip.to_s == '11.22.33.0' }
|
34
|
+
assert { r.bits == 24 }
|
35
|
+
assert { r.netmask == '255.255.255.0' }
|
38
36
|
end
|
39
37
|
|
40
38
|
it "parses shortened slash notation with a netmask" do
|
41
39
|
r = CIDR['11.22/255.255.0.0']
|
42
|
-
r.ip.
|
43
|
-
r.ip.to_s
|
44
|
-
r.bits
|
45
|
-
r.netmask
|
40
|
+
assert { r.ip.is_a? IP }
|
41
|
+
assert { r.ip.to_s == '11.22.0.0' }
|
42
|
+
assert { r.bits == 16 }
|
43
|
+
assert { r.netmask == '255.255.0.0' }
|
46
44
|
end
|
47
45
|
|
48
46
|
it "supports wrapping" do
|
49
47
|
r = CIDR['11.22.33.44/24']
|
50
48
|
wrapped = CIDR[r]
|
51
|
-
wrapped.
|
52
|
-
r.object_id
|
49
|
+
assert { wrapped.is_a? CIDR }
|
50
|
+
assert { r.object_id == wrapped.object_id }
|
53
51
|
end
|
54
52
|
|
55
53
|
it "fetches a random CIDR" do
|
56
|
-
CIDR.rand.
|
54
|
+
assert { CIDR.rand.is_a? CIDR }
|
57
55
|
end
|
58
56
|
|
59
57
|
it "knows its bits" do
|
60
58
|
i = rand(33)
|
61
|
-
CIDR["1.1.1.1/#{i}"].bits
|
62
|
-
should == i
|
59
|
+
assert { CIDR["1.1.1.1/#{i}"].bits == i }
|
63
60
|
end
|
64
61
|
|
65
62
|
it "knows its ip" do
|
66
|
-
CIDR['11.22.33.44/20'].ip.
|
67
|
-
should == IP['11.22.33.44']
|
63
|
+
assert { CIDR['11.22.33.44/20'].ip == IP['11.22.33.44'] }
|
68
64
|
end
|
69
65
|
|
70
66
|
it "knows its netmask" do
|
71
|
-
CIDR['11.22.33.44/20'].netmask.
|
72
|
-
|
73
|
-
|
74
|
-
CIDR['
|
75
|
-
should == IP['255.0.0.0']
|
76
|
-
|
77
|
-
CIDR['11.22.33.44/32'].netmask.
|
78
|
-
should == IP['255.255.255.255']
|
79
|
-
|
80
|
-
CIDR['1.1.1.1/0'].netmask.
|
81
|
-
should == IP['0.0.0.0']
|
67
|
+
assert { CIDR['11.22.33.44/20'].netmask == IP['255.255.240.0'] }
|
68
|
+
assert { CIDR['11.22.33.44/8'].netmask == IP['255.0.0.0'] }
|
69
|
+
assert { CIDR['11.22.33.44/32'].netmask == IP['255.255.255.255'] }
|
70
|
+
assert { CIDR['1.1.1.1/0'].netmask == IP['0.0.0.0'] }
|
82
71
|
end
|
83
72
|
|
84
73
|
it "knows its min" do
|
85
|
-
CIDR['11.22.33.44/20'].min.
|
86
|
-
|
87
|
-
|
88
|
-
CIDR['11.22.33.44/
|
89
|
-
should == IP['11.0.0.0']
|
90
|
-
|
91
|
-
CIDR['11.22.33.44/32'].min.
|
92
|
-
should == IP['11.22.33.44']
|
93
|
-
|
94
|
-
CIDR['11.22.33.44/0'].min.
|
95
|
-
should == IP['0.0.0.0']
|
74
|
+
assert { CIDR['11.22.33.44/20'].min == IP['11.22.32.0'] }
|
75
|
+
assert { CIDR['11.22.33.44/8'].min == IP['11.0.0.0'] }
|
76
|
+
assert { CIDR['11.22.33.44/32'].min == IP['11.22.33.44'] }
|
77
|
+
assert { CIDR['11.22.33.44/0'].min == IP['0.0.0.0'] }
|
96
78
|
end
|
97
79
|
|
98
80
|
it "knows its max" do
|
99
|
-
CIDR['11.22.33.44/20'].max.
|
100
|
-
|
101
|
-
|
102
|
-
CIDR['11.22.33.44/
|
103
|
-
should == IP['11.255.255.255']
|
104
|
-
|
105
|
-
CIDR['11.22.33.44/32'].max.
|
106
|
-
should == IP['11.22.33.44']
|
107
|
-
|
108
|
-
CIDR['11.22.33.44/0'].max.
|
109
|
-
should == IP['255.255.255.255']
|
81
|
+
assert { CIDR['11.22.33.44/20'].max == IP['11.22.47.255'] }
|
82
|
+
assert { CIDR['11.22.33.44/8'].max == IP['11.255.255.255'] }
|
83
|
+
assert { CIDR['11.22.33.44/32'].max == IP['11.22.33.44'] }
|
84
|
+
assert { CIDR['11.22.33.44/0'].max == IP['255.255.255.255'] }
|
110
85
|
end
|
111
86
|
|
112
87
|
it "knows its rest field" do
|
113
|
-
CIDR['11.22.33.44/20'].rest_field.
|
114
|
-
|
115
|
-
|
116
|
-
CIDR['11.22.33.44/
|
117
|
-
should == IP['0.22.33.44']
|
118
|
-
|
119
|
-
CIDR['11.22.33.44/32'].rest_field.
|
120
|
-
should == IP['0.0.0.0']
|
121
|
-
|
122
|
-
CIDR['11.22.33.44/0'].rest_field.
|
123
|
-
should == IP['11.22.33.44']
|
88
|
+
assert { CIDR['11.22.33.44/20'].rest_field == IP['0.0.1.44'] }
|
89
|
+
assert { CIDR['11.22.33.44/8'].rest_field == IP['0.22.33.44'] }
|
90
|
+
assert { CIDR['11.22.33.44/32'].rest_field == IP['0.0.0.0'] }
|
91
|
+
assert { CIDR['11.22.33.44/0'].rest_field == IP['11.22.33.44'] }
|
124
92
|
end
|
125
93
|
|
126
94
|
it "knows its size" do
|
127
|
-
CIDR['11.22.33.44/20'].size
|
128
|
-
|
129
|
-
|
130
|
-
CIDR['11.22.33.44/
|
131
|
-
should == 0x1000000
|
132
|
-
|
133
|
-
CIDR['11.22.33.44/32'].size.
|
134
|
-
should == 1
|
135
|
-
|
136
|
-
CIDR['11.22.33.44/0'].size.
|
137
|
-
should == 0x100000000
|
95
|
+
assert { CIDR['11.22.33.44/20'].size == 0x1000 }
|
96
|
+
assert { CIDR['11.22.33.44/8'].size == 0x1000000 }
|
97
|
+
assert { CIDR['11.22.33.44/32'].size == 1 }
|
98
|
+
assert { CIDR['11.22.33.44/0'].size == 0x100000000 }
|
138
99
|
end
|
139
100
|
|
140
101
|
it "is enumerable" do
|
141
102
|
r = CIDR['11.22.33.44/24']
|
142
|
-
r.
|
143
|
-
CIDR.included_modules.
|
103
|
+
assert { r.respond_to? :each }
|
104
|
+
assert { CIDR.included_modules.include? Enumerable }
|
144
105
|
|
145
106
|
a = r.to_a
|
146
107
|
|
147
|
-
a.size
|
148
|
-
a.first
|
149
|
-
a.last
|
108
|
+
assert { a.size == r.size }
|
109
|
+
assert { a.first == r.first }
|
110
|
+
assert { a.last == r.last }
|
150
111
|
end
|
151
112
|
|
152
113
|
it "tests inclusion" do
|
153
114
|
r = CIDR['11.22.33.44/24']
|
154
|
-
r.
|
155
|
-
r.
|
156
|
-
r.
|
157
|
-
r.
|
158
|
-
r.
|
115
|
+
assert { r.respond_to? :include? }
|
116
|
+
assert { r.include? '11.22.33.0' }
|
117
|
+
assert { r.include? IP['11.22.33.255'] }
|
118
|
+
deny { r.include? IP['11.22.32.44'].to_i }
|
119
|
+
deny { r.include? '11.22.34.44' }
|
159
120
|
end
|
160
121
|
|
161
122
|
end
|
data/spec/ip_spec.rb
CHANGED
@@ -1,20 +1,18 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
1
|
describe IP do
|
4
2
|
it "parses a string" do
|
5
3
|
ip = IP['11.22.33.44']
|
6
|
-
ip.
|
7
|
-
ip.inspect.
|
4
|
+
assert { ip.is_a? IP }
|
5
|
+
assert { ip.inspect.include? '11.22.33.44' }
|
8
6
|
end
|
9
7
|
|
10
8
|
it "parses an integer" do
|
11
9
|
ip = IP[255]
|
12
|
-
ip.
|
13
|
-
ip.inspect.
|
10
|
+
assert { ip.is_a? IP }
|
11
|
+
assert { ip.inspect.include? '0.0.0.255' }
|
14
12
|
|
15
13
|
ip = IP[0xA00A10FF]
|
16
|
-
ip.
|
17
|
-
ip.inspect.
|
14
|
+
assert { ip.is_a? IP }
|
15
|
+
assert { ip.inspect.include? '160.10.16.255' }
|
18
16
|
end
|
19
17
|
|
20
18
|
it "parses an array of int-ish objects" do
|
@@ -25,86 +23,89 @@ describe IP do
|
|
25
23
|
end.new
|
26
24
|
|
27
25
|
ip = IP[[7, '42', four, nil]]
|
28
|
-
ip.
|
29
|
-
ip.inspect.
|
26
|
+
assert { ip.is_a? IP }
|
27
|
+
assert { ip.inspect.include? '7.42.4.0' }
|
30
28
|
end
|
31
29
|
|
32
30
|
it "parses nil" do
|
33
31
|
ip = IP[nil]
|
34
|
-
ip.
|
35
|
-
ip.inspect.
|
32
|
+
assert { ip.is_a? IP }
|
33
|
+
assert { ip.inspect.include? '0.0.0.0' }
|
36
34
|
end
|
37
35
|
|
38
36
|
it "parses an IP" do
|
39
37
|
ip = IP['11.22.33.44']
|
40
|
-
|
41
|
-
IP[ip].
|
38
|
+
|
39
|
+
assert { IP[ip].is_a? IP }
|
40
|
+
assert { IP[ip].object_id == ip.object_id }
|
42
41
|
end
|
43
42
|
|
44
43
|
it "knows its integer representation" do
|
45
44
|
i = rand(0xFFFFFFFF)
|
46
|
-
IP[i].to_i
|
45
|
+
assert { IP[i].to_i == i }
|
47
46
|
end
|
48
47
|
|
49
48
|
it "knows its string representation" do
|
50
|
-
IP['11.22.33.44'].to_s
|
49
|
+
assert { IP['11.22.33.44'].to_s == '11.22.33.44' }
|
51
50
|
end
|
52
51
|
|
53
52
|
it "knows its octets" do
|
54
|
-
IP['44.33.22.11'].octets
|
53
|
+
assert { IP['44.33.22.11'].octets == [44, 33, 22, 11] }
|
55
54
|
end
|
56
55
|
|
57
56
|
it "knows the max" do
|
58
|
-
IP
|
59
|
-
IP.max.
|
60
|
-
IP.max.to_s.should == '255.255.255.255'
|
57
|
+
assert { IP.max.to_i == 0xFFFFFFFF }
|
58
|
+
assert { IP.max.to_s == '255.255.255.255' }
|
61
59
|
end
|
62
60
|
|
63
61
|
it "fetches a random ip" do
|
64
|
-
IP.rand.
|
62
|
+
assert { IP.rand.is_a? IP }
|
65
63
|
end
|
66
64
|
|
67
65
|
it "is comparable" do
|
68
|
-
IP.included_modules.
|
69
|
-
|
66
|
+
assert { IP.included_modules.include? Comparable }
|
67
|
+
|
68
|
+
assert { IP.public_methods.include? :<=> }
|
70
69
|
|
71
70
|
i1, i2 = rand(0xFFFFFFFF), rand(0xFFFFFFFF)
|
72
|
-
(IP[i1] <=> IP[i2])
|
71
|
+
assert { (IP[i1] <=> IP[i2]) == (i1 <=> i2) }
|
73
72
|
end
|
74
73
|
|
75
74
|
it "can add, subtract, and succ" do
|
76
75
|
i1, i2 = rand(0xFFFFFFF), rand(0xFFFFFFF)
|
77
76
|
ip1 = IP[i1]
|
78
77
|
ipsum = IP[i1] + i2
|
79
|
-
ipsum.
|
80
|
-
ipsum.to_i
|
78
|
+
assert { ipsum.is_a? IP }
|
79
|
+
assert { ipsum.to_i == i1 + i2 }
|
81
80
|
|
82
|
-
ip1.succ.to_i
|
83
|
-
(ipsum - i2).to_i
|
84
|
-
(ipsum - ip1).to_i
|
81
|
+
assert { ip1.succ.to_i == i1 + 1 }
|
82
|
+
assert { (ipsum - i2).to_i == i1 }
|
83
|
+
assert { (ipsum - ip1).to_i == i2 }
|
85
84
|
end
|
86
85
|
|
87
86
|
it "knows its prefix and rest field given a netmask" do
|
88
87
|
ip = IP['11.22.33.44']
|
89
88
|
|
90
|
-
ip.prefix('255.255.255.0')
|
91
|
-
ip.rest_field('255.255.255.0')
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
ip.
|
97
|
-
|
98
|
-
|
89
|
+
assert { ip.prefix('255.255.255.0') == IP['11.22.33.00'] }
|
90
|
+
assert { ip.rest_field('255.255.255.0') == IP['0.0.0.44'] }
|
91
|
+
assert {
|
92
|
+
(ip.prefix('255.255.255.0') + ip.rest_field('255.255.255.0')) == ip
|
93
|
+
}
|
94
|
+
|
95
|
+
assert { ip.prefix('255.255.240.0') == IP['11.22.32.00'] }
|
96
|
+
assert { ip.rest_field('255.255.240.0') == IP['0.0.1.44'] }
|
97
|
+
assert {
|
98
|
+
(ip.prefix('255.255.240.0') + ip.rest_field('255.255.240.0')) == ip
|
99
|
+
}
|
99
100
|
end
|
100
101
|
|
101
102
|
it "knows whether it's a netmask" do
|
102
103
|
zero_bits = rand(32)
|
103
104
|
(0..32).each do |bits|
|
104
|
-
IP[(0xFFFFFFFF >> bits) << bits].
|
105
|
+
assert { IP[(0xFFFFFFFF >> bits) << bits].netmask? }
|
105
106
|
end
|
106
107
|
|
107
|
-
IP['1.2.3.4'].
|
108
|
-
IP['0.255.0.0'].
|
108
|
+
deny { IP['1.2.3.4'].netmask? }
|
109
|
+
deny { IP['0.255.0.0'].netmask? }
|
109
110
|
end
|
110
111
|
end
|
data/spec/radix_spec.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe "Radix" do
|
1
|
+
describe "Fixnum#radix" do
|
4
2
|
let(:lim) { 50 + rand(100) }
|
5
3
|
let(:rad) { 2 + rand(9) }
|
6
4
|
|
7
5
|
it "calculates radix" do
|
8
6
|
(1..lim).each do |i|
|
9
|
-
i.radix(rad).join
|
7
|
+
assert { i.radix(rad).join == i.to_s(rad) }
|
10
8
|
end
|
11
9
|
end
|
12
10
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iplogic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,21 +9,10 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: rspec
|
16
|
-
requirement: &12043080 !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '1.0'
|
22
|
-
type: :development
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: *12043080
|
12
|
+
date: 2012-05-03 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
25
14
|
description: An IPv4 swiss-army chainsaw
|
26
|
-
email:
|
15
|
+
email: jjmadkisson@gmail.com
|
27
16
|
executables: []
|
28
17
|
extensions: []
|
29
18
|
extra_rdoc_files:
|
@@ -43,7 +32,7 @@ files:
|
|
43
32
|
- spec/cidr_spec.rb
|
44
33
|
- spec/spec_helper.rb
|
45
34
|
- spec/radix_spec.rb
|
46
|
-
homepage: http://github.com/
|
35
|
+
homepage: http://github.com/jayferd/iplogic
|
47
36
|
licenses: []
|
48
37
|
post_install_message:
|
49
38
|
rdoc_options: []
|
@@ -72,3 +61,4 @@ test_files:
|
|
72
61
|
- spec/cidr_spec.rb
|
73
62
|
- spec/spec_helper.rb
|
74
63
|
- spec/radix_spec.rb
|
64
|
+
has_rdoc:
|