iplogic 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -8,4 +8,4 @@ Usage:
8
8
  ip = IP('11.22.33.44')
9
9
  cidr = CIDR('11.22.32.00/20')
10
10
 
11
- Look in `spec/ip_spec.rb` for a neat summary of al the methods available.
11
+ Look in `spec/ip_spec.rb` and `spec/cidr_spec.rb` for a neat summary of al the methods available.
data/Rakefile CHANGED
@@ -1,12 +1,18 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
3
 
4
- begin
5
- require 'spec/rake/spectask'
6
- Spec::Rake::SpecTask.new('spec') do |t|
7
- t.spec_files = FileList['spec/**/*_spec.rb']
8
- t.ruby_opts = ["-r spec/spec_helper.rb"]
9
- end
10
- rescue LoadError
11
- #pass. rspec is not required
4
+ # begin
5
+ task :spec do
6
+ sh "rspec -I spec/ spec/*_spec.rb"
12
7
  end
8
+
9
+ # require 'rspec/rake'
10
+ # Spec::Rake::SpecTask.new('spec') do |t|
11
+ # t.spec_files = FileList['spec/**/*_spec.rb']
12
+ # t.ruby_opts = ["-r spec/spec_helper.rb"]
13
+ # end
14
+
15
+ task :default => [:spec]
16
+ # rescue LoadError
17
+ # #pass. rspec is not required
18
+ # end
@@ -1,4 +1,4 @@
1
- require 'lib/iplogic'
1
+ require './lib/iplogic'
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'iplogic'
@@ -1,5 +1,5 @@
1
1
  module IPLogic
2
- VERSION = '0.1.4'
2
+ VERSION = '0.2.0'
3
3
 
4
4
  LIB = File.expand_path(File.dirname(__FILE__))
5
5
  end
@@ -2,8 +2,38 @@ module IPLogic
2
2
  class CIDR
3
3
  include Enumerable
4
4
 
5
- SHORTENED_IP_REGEX = /^(\d{1,3}(\.\d{1,3}){1,3})\/(\d+)$/
5
+ # raised if bad arguments are passed to CIDR.wrap
6
+ FormatError = Class.new(ArgumentError)
7
+
8
+ # matches a shortened CIDR: `xxx.xxx.xxx/xx`
9
+ SHORTENED_CIDR_REGEX = /^(\d{1,3}(\.\d{1,3}){1,3})\/(\d+)$/
10
+
6
11
  class << self
12
+ # Where the magic happens.
13
+ # @raise FormatError
14
+ # @overload CIDR.wrap(cidr)
15
+ # @param [CIDR] cidr
16
+ # Returns the cidr. Useful for typecasting.
17
+ # @return [CIDR] a CIDR
18
+ # @overload CIDR.wrap(string)
19
+ # @param [String] string
20
+ # Parses `string` as a CIDR. The following formats are accepted:
21
+ #
22
+ # "#{partial_ip}/#{bits}":
23
+ # CIDR.wrap('11.22.33.44/16') # => #<CIDR[ 11.22.33.44/16 ]>
24
+ # CIDR.wrap('10.0.1/24') # => #<CIDR[ 10.0.1.0/24 ]>
25
+ #
26
+ # "#{partial_ip}/#{netmask}":
27
+ # CIDR.wrap('11.22.33.44/255.255.0.0') # => #<CIDR[ 11.22.33.44/16 ]>
28
+ # CIDR.wrap('10.0.1/255.255.255.0') # => #<CIDR[ 10.0.1.0/24 ]>
29
+ # @return [CIDR] a CIDR
30
+ # @overload CIDR.wrap(ip_ish, netmask_or_bits)
31
+ # @param [IP] ip_ish
32
+ # the address of the network. Will be passed through `IP.wrap`.
33
+ # @param [Fixnum IP] netmask_or_bits
34
+ # the netmask or the number of addressable bits
35
+ # (the thing after the / in standard CIDR notation)
36
+ #
7
37
  def wrap(*args)
8
38
  return args.first if args.first.is_a? CIDR
9
39
  if args.size == 2
@@ -34,11 +64,11 @@ module IPLogic
34
64
  # one argument means it's gotta be a string to parse
35
65
  format_error(arg) unless arg.is_a? String
36
66
 
37
- if arg =~ SHORTENED_IP_REGEX
67
+ if arg =~ SHORTENED_CIDR_REGEX
38
68
  new(parse_shortened_ip($1), $3)
39
- elsif (parts = arg.split('/')).size == 2
40
- ip = parse_shortened_ip(parts[0])
41
- mask = IP.wrap(parts[1])
69
+ elsif (octets = arg.split('/')).size == 2
70
+ ip = parse_shortened_ip(octets[0])
71
+ mask = IP.wrap(octets[1])
42
72
  return new(ip, netmask_to_bits(mask))
43
73
  else
44
74
  format_error(arg)
@@ -46,6 +76,14 @@ module IPLogic
46
76
  end
47
77
  end
48
78
 
79
+ alias [] wrap
80
+
81
+ # @return a random CIDR
82
+ def rand
83
+ # both /32 and /0 are valid
84
+ wrap(IP.rand, Kernel.rand(33))
85
+ end
86
+
49
87
  private
50
88
  # helper for formats like 11.22.33/24
51
89
  # just adds some .0's to the end
@@ -56,20 +94,34 @@ module IPLogic
56
94
 
57
95
  def netmask_to_bits(netmask)
58
96
  raise FormatError, "CIDR: #{netmask} is not a netmask" unless netmask.netmask?
59
- # TODO: there's probably a clever mathy way to do this,
60
- # but this works just fine.
61
- netmask.to_i.to_s(2) =~ /^(1*)0*$/
62
- $1.length
97
+
98
+ maxint32 = 0xFFFFFFFF
99
+ t = 1 + (maxint32 - netmask.to_i)
100
+
101
+ # netmask.to_i.to_s(2) =~ /^(1*)0*$/
102
+ # $1.length
103
+
104
+ # poor man's log_2
105
+ res = -1
106
+ while t > 0
107
+ res += 1
108
+ t >>= 1
109
+ end
110
+
111
+ 32 - res
63
112
  end
64
113
 
65
- FormatError = Class.new(ArgumentError)
66
114
  def format_error(*args)
67
115
  args = args.map { |a| a.inspect }.join(', ')
68
116
  raise FormatError, "CIDR: unable to parse #{args}"
69
117
  end
70
118
  end
71
119
 
72
- attr_reader :ip, :bits
120
+ # @return [IP] the address of the network
121
+ attr_reader :ip
122
+
123
+ # @return [Fixnum] the /n value
124
+ attr_reader :bits
73
125
  alias prefix_length bits
74
126
 
75
127
  def initialize(ip, bits)
@@ -77,33 +129,47 @@ module IPLogic
77
129
  @ip = IP.wrap(ip)
78
130
  end
79
131
 
132
+ # CIDR of all possible IP addresses.
133
+ # Equivalent to `CIDR('0.0.0.0/0')`
80
134
  ALL = self.new(0,0)
135
+
136
+ # Getter for CIDR::ALL
137
+ # @see ALL
81
138
  def self.all
82
139
  ALL
83
140
  end
84
141
 
142
+ # The number of bits allocated to the network
85
143
  def inv_bits
86
144
  32 - bits
87
145
  end
88
146
 
147
+ # @return [String] `#<CIDR [ 10.0.1.0/24 ]>`
89
148
  def inspect
90
149
  "#<CIDR [ #{self} ]>"
91
150
  end
92
151
 
152
+ # the CIDR's netmask
153
+ # @return [IP] the netmask
93
154
  def netmask
94
155
  @netmask ||= IP.wrap(
95
156
  ((1 << bits) - 1) << (32 - bits)
96
157
  )
97
158
  end
98
159
 
160
+ # The number of addresses in the CIDR
99
161
  def size
100
162
  @size ||= (1 << inv_bits)
101
163
  end
102
164
 
165
+ # Test whether an address is on the network
166
+ # @param [IP] ip_ish the IP-ish to test.
103
167
  def include?(ip)
104
168
  IP.wrap(ip).min(bits) == min
105
169
  end
106
170
 
171
+ # the lowest address on the network
172
+ # @return [IP] the minimum address
107
173
  def min
108
174
  @min ||= IP.wrap(
109
175
  (ip.to_i >> inv_bits) << inv_bits
@@ -113,38 +179,57 @@ module IPLogic
113
179
  alias first min
114
180
  alias prefix min
115
181
 
182
+ # the maximum address on the network
183
+ # @return [IP] the maximum address
116
184
  def max
117
185
  @max ||= min + (size - 1)
118
186
  end
119
187
  alias :end :max
120
188
  alias last max
121
189
 
190
+ # the "rest" field is the part of the address after the
191
+ # netmask is applied.
192
+ # See RFC 791.
122
193
  def rest_field
123
194
  @rest_field ||= ip - min
124
195
  end
125
196
  alias rest rest_field
126
197
 
198
+ # The usual CIDR representation
127
199
  def to_s
128
200
  "#{ip}/#{bits}"
129
201
  end
130
202
  alias to_str to_s
131
203
 
204
+ # The number of significant octets in an address on this network.
205
+ #
206
+ # @example
207
+ # CIDR('0.0.0.0/0').significant_octets # => 4
208
+ # CIDR('10.0.0.0/8').significant_octets # => 3
209
+ # CIDR('10.10.0.0/16').significant_octets # => 2
210
+ # CIDR('10.10.0.0/20').significant_octets # => 2
211
+ # CIDR('10.10.0.0/24').significant_octets # => 1
212
+ # CIDR('10.10.0.1/32').significant_octets # => 0
132
213
  def significant_octets
133
214
  4 - (bits / 8)
134
215
  end
135
216
 
217
+ # The smallest classful DNS zone that will capture the range.
218
+ # NB: may not be applicable to your DNS configs, see RFC 2317
219
+ # @example
220
+ # CIDR('10.0.1/24').zone # => "1.0.10"
221
+ # @return [String] the zone
136
222
  def zone
137
- ip.parts[0..-(1+significant_octets)].reverse.join('.')
223
+ ip.octets[0..-(1+significant_octets)].reverse.join('.')
138
224
  end
139
225
 
226
+ # Iterates over every address in the CIDR.
227
+ # NB: this might be huge - 2**bits
228
+ # @yield [IP] an address in the CIDR
229
+ # @return [CIDR] self
140
230
  def each(&blk)
141
231
  (min..max).each(&blk)
232
+ self
142
233
  end
143
234
  end
144
-
145
- def CIDR(*args)
146
- return CIDR if args.empty?
147
-
148
- CIDR.wrap(*args)
149
- end
150
235
  end
@@ -34,9 +34,9 @@ module IPLogic
34
34
 
35
35
  int = case arg
36
36
  when Array
37
- parts_to_int(arg)
37
+ octets_to_int(arg)
38
38
  when String
39
- parts_to_int(arg.split('.'))
39
+ octets_to_int(arg.split('.'))
40
40
  when Fixnum
41
41
  arg
42
42
  when nil
@@ -45,16 +45,27 @@ module IPLogic
45
45
  raise FormatError, "IP: Unable to parse #{arg.inspect}"
46
46
  end
47
47
 
48
+ unless (0..0xFFFFFFFF).include? int
49
+ raise FormatError, "IP: Address #{arg.inspect} out of range"
50
+ end
51
+
48
52
  return new(int)
49
53
  end
50
54
 
55
+ alias [] wrap
56
+
51
57
  FormatError = Class.new(ArgumentError)
52
58
 
59
+ # Return a random IP address. Useful for mocks / tests
60
+ def rand
61
+ wrap(Kernel.rand(0x100000000))
62
+ end
63
+
53
64
  private
54
- def parts_to_int(parts)
65
+ def octets_to_int(octets)
55
66
  r = 0
56
- parts.reverse.each_with_index do |part, i|
57
- r += (part.to_i << 8*i)
67
+ octets.reverse.each_with_index do |octet, i|
68
+ r += (octet.to_i << 8*i)
58
69
  end
59
70
  r
60
71
  end
@@ -65,7 +76,7 @@ module IPLogic
65
76
  alias to_i int
66
77
  alias to_int int
67
78
 
68
- def initialize(int)
79
+ def initialize(int, extra={})
69
80
  @int = int
70
81
  end
71
82
 
@@ -75,17 +86,17 @@ module IPLogic
75
86
  MAXIP
76
87
  end
77
88
 
78
- def parts
79
- @parts ||= begin
89
+ def octets
90
+ @octets ||= begin
80
91
  rad = int.radix(256)
81
92
  [0]*([4-rad.size,0].max) + rad
82
93
  end
83
94
  end
95
+ alias parts octets
84
96
 
85
97
  def to_s
86
- parts.join('.')
98
+ octets.join('.')
87
99
  end
88
- alias to_str to_s
89
100
 
90
101
  def inspect
91
102
  "#<IP [ #{self} ]>"
@@ -145,9 +156,4 @@ module IPLogic
145
156
  msg
146
157
  end
147
158
  end
148
-
149
- def IP(*args)
150
- return IP if args.empty?
151
- IP.wrap(args.first)
152
- end
153
159
  end
@@ -2,27 +2,27 @@ require File.join(File.dirname(__FILE__), 'spec_helper')
2
2
 
3
3
  describe CIDR do
4
4
  it "parses an IP-ish and netmask-ish" do
5
- r = CIDR('4.33.222.111', '255.255.240.0')
5
+ r = CIDR['4.33.222.111', '255.255.240.0']
6
6
  r.should be_a CIDR
7
7
  r.inspect.should include '4.33.222.111/20'
8
8
 
9
- r = CIDR(IP('4.33.222.111'), 20)
9
+ r = CIDR[IP['4.33.222.111'], 20]
10
10
  r.should be_a CIDR
11
11
  r.inspect.should include '4.33.222.111/20'
12
12
 
13
- r = CIDR('4.33.222.111', IP('255.255.240.0'))
13
+ r = CIDR['4.33.222.111', IP['255.255.240.0']]
14
14
  r.should be_a CIDR
15
15
  r.inspect.should include '4.33.222.111/20'
16
16
  end
17
17
 
18
18
  it "parses slash notation" do
19
- r = CIDR('11.22.33.44/8')
19
+ r = CIDR['11.22.33.44/8']
20
20
  r.should be_a CIDR
21
21
  r.inspect.should include '11.22.33.44/8'
22
22
  end
23
23
 
24
24
  it "parses slash notation with a netmask" do
25
- r = CIDR('11.22.33.44/255.255.255.0')
25
+ r = CIDR['11.22.33.44/255.255.255.0']
26
26
  r.ip.should be_a IP
27
27
  r.ip.to_s.should == '11.22.33.44'
28
28
  r.bits.should == 24
@@ -30,7 +30,7 @@ describe CIDR do
30
30
  end
31
31
 
32
32
  it "parses shortened slash notation" do
33
- r = CIDR('11.22.33/24')
33
+ r = CIDR['11.22.33/24']
34
34
  r.ip.should be_a IP
35
35
  r.ip.to_s.should == '11.22.33.0'
36
36
  r.bits.should == 24
@@ -38,7 +38,7 @@ describe CIDR do
38
38
  end
39
39
 
40
40
  it "parses shortened slash notation with a netmask" do
41
- r = CIDR('11.22/255.255.0.0')
41
+ r = CIDR['11.22/255.255.0.0']
42
42
  r.ip.should be_a IP
43
43
  r.ip.to_s.should == '11.22.0.0'
44
44
  r.bits.should == 16
@@ -46,95 +46,99 @@ describe CIDR do
46
46
  end
47
47
 
48
48
  it "supports wrapping" do
49
- r = CIDR('11.22.33.44/24')
50
- wrapped = CIDR(r)
49
+ r = CIDR['11.22.33.44/24']
50
+ wrapped = CIDR[r]
51
51
  wrapped.should be_a CIDR
52
52
  r.object_id.should == wrapped.object_id
53
53
  end
54
54
 
55
+ it "fetches a random CIDR" do
56
+ CIDR.rand.should be_a CIDR
57
+ end
58
+
55
59
  it "knows its bits" do
56
60
  i = rand(33)
57
- CIDR("1.1.1.1/#{i}").bits.
61
+ CIDR["1.1.1.1/#{i}"].bits.
58
62
  should == i
59
63
  end
60
64
 
61
65
  it "knows its ip" do
62
- CIDR('11.22.33.44/20').ip.
63
- should == IP('11.22.33.44')
66
+ CIDR['11.22.33.44/20'].ip.
67
+ should == IP['11.22.33.44']
64
68
  end
65
69
 
66
70
  it "knows its netmask" do
67
- CIDR('11.22.33.44/20').netmask.
68
- should == IP('255.255.240.0')
71
+ CIDR['11.22.33.44/20'].netmask.
72
+ should == IP['255.255.240.0']
69
73
 
70
- CIDR('11.22.33.44/8').netmask.
71
- should == IP('255.0.0.0')
74
+ CIDR['11.22.33.44/8'].netmask.
75
+ should == IP['255.0.0.0']
72
76
 
73
- CIDR('11.22.33.44/32').netmask.
74
- should == IP('255.255.255.255')
77
+ CIDR['11.22.33.44/32'].netmask.
78
+ should == IP['255.255.255.255']
75
79
 
76
- CIDR('1.1.1.1/0').netmask.
77
- should == IP('0.0.0.0')
80
+ CIDR['1.1.1.1/0'].netmask.
81
+ should == IP['0.0.0.0']
78
82
  end
79
83
 
80
84
  it "knows its min" do
81
- CIDR('11.22.33.44/20').min.
82
- should == IP('11.22.32.0')
85
+ CIDR['11.22.33.44/20'].min.
86
+ should == IP['11.22.32.0']
83
87
 
84
- CIDR('11.22.33.44/8').min.
85
- should == IP('11.0.0.0')
88
+ CIDR['11.22.33.44/8'].min.
89
+ should == IP['11.0.0.0']
86
90
 
87
- CIDR('11.22.33.44/32').min.
88
- should == IP('11.22.33.44')
91
+ CIDR['11.22.33.44/32'].min.
92
+ should == IP['11.22.33.44']
89
93
 
90
- CIDR('11.22.33.44/0').min.
91
- should == IP('0.0.0.0')
94
+ CIDR['11.22.33.44/0'].min.
95
+ should == IP['0.0.0.0']
92
96
  end
93
97
 
94
98
  it "knows its max" do
95
- CIDR('11.22.33.44/20').max.
96
- should == IP('11.22.47.255')
99
+ CIDR['11.22.33.44/20'].max.
100
+ should == IP['11.22.47.255']
97
101
 
98
- CIDR('11.22.33.44/8').max.
99
- should == IP('11.255.255.255')
102
+ CIDR['11.22.33.44/8'].max.
103
+ should == IP['11.255.255.255']
100
104
 
101
- CIDR('11.22.33.44/32').max.
102
- should == IP('11.22.33.44')
105
+ CIDR['11.22.33.44/32'].max.
106
+ should == IP['11.22.33.44']
103
107
 
104
- CIDR('11.22.33.44/0').max.
105
- should == IP('255.255.255.255')
108
+ CIDR['11.22.33.44/0'].max.
109
+ should == IP['255.255.255.255']
106
110
  end
107
111
 
108
112
  it "knows its rest field" do
109
- CIDR('11.22.33.44/20').rest_field.
110
- should == IP('0.0.1.44')
113
+ CIDR['11.22.33.44/20'].rest_field.
114
+ should == IP['0.0.1.44']
111
115
 
112
- CIDR('11.22.33.44/8').rest_field.
113
- should == IP('0.22.33.44')
116
+ CIDR['11.22.33.44/8'].rest_field.
117
+ should == IP['0.22.33.44']
114
118
 
115
- CIDR('11.22.33.44/32').rest_field.
116
- should == IP('0.0.0.0')
119
+ CIDR['11.22.33.44/32'].rest_field.
120
+ should == IP['0.0.0.0']
117
121
 
118
- CIDR('11.22.33.44/0').rest_field.
119
- should == IP('11.22.33.44')
122
+ CIDR['11.22.33.44/0'].rest_field.
123
+ should == IP['11.22.33.44']
120
124
  end
121
125
 
122
126
  it "knows its size" do
123
- CIDR('11.22.33.44/20').size.
127
+ CIDR['11.22.33.44/20'].size.
124
128
  should == 0x1000
125
129
 
126
- CIDR('11.22.33.44/8').size.
130
+ CIDR['11.22.33.44/8'].size.
127
131
  should == 0x1000000
128
132
 
129
- CIDR('11.22.33.44/32').size.
133
+ CIDR['11.22.33.44/32'].size.
130
134
  should == 1
131
135
 
132
- CIDR('11.22.33.44/0').size.
136
+ CIDR['11.22.33.44/0'].size.
133
137
  should == 0x100000000
134
138
  end
135
139
 
136
140
  it "is enumerable" do
137
- r = CIDR('11.22.33.44/24')
141
+ r = CIDR['11.22.33.44/24']
138
142
  r.should respond_to :each
139
143
  CIDR.included_modules.should include Enumerable
140
144
 
@@ -146,11 +150,11 @@ describe CIDR do
146
150
  end
147
151
 
148
152
  it "tests inclusion" do
149
- r = CIDR('11.22.33.44/24')
153
+ r = CIDR['11.22.33.44/24']
150
154
  r.should respond_to :include?
151
155
  r.should include '11.22.33.0'
152
- r.should include IP('11.22.33.255')
153
- r.should_not include IP('11.22.32.44').to_i
156
+ r.should include IP['11.22.33.255']
157
+ r.should_not include IP['11.22.32.44'].to_i
154
158
  r.should_not include '11.22.34.44'
155
159
  end
156
160
 
@@ -2,17 +2,17 @@ require File.join(File.dirname(__FILE__), 'spec_helper')
2
2
 
3
3
  describe IP do
4
4
  it "parses a string" do
5
- ip = IP('11.22.33.44')
5
+ ip = IP['11.22.33.44']
6
6
  ip.should be_a IP
7
7
  ip.inspect.should include '11.22.33.44'
8
8
  end
9
9
 
10
10
  it "parses an integer" do
11
- ip = IP(255)
11
+ ip = IP[255]
12
12
  ip.should be_a IP
13
13
  ip.inspect.should include '0.0.0.255'
14
14
 
15
- ip = IP(0xA00A10FF)
15
+ ip = IP[0xA00A10FF]
16
16
  ip.should be_a IP
17
17
  ip.inspect.should include '160.10.16.255'
18
18
  end
@@ -24,34 +24,34 @@ describe IP do
24
24
  end
25
25
  end.new
26
26
 
27
- ip = IP([7, '42', four, nil])
27
+ ip = IP[[7, '42', four, nil]]
28
28
  ip.should be_a IP
29
29
  ip.inspect.should include '7.42.4.0'
30
30
  end
31
31
 
32
32
  it "parses nil" do
33
- ip = IP(nil)
33
+ ip = IP[nil]
34
34
  ip.should be_a IP
35
35
  ip.inspect.should include '0.0.0.0'
36
36
  end
37
37
 
38
38
  it "parses an IP" do
39
- ip = IP('11.22.33.44')
40
- IP(ip).should be_a IP
41
- IP(ip).object_id.should == ip.object_id
39
+ ip = IP['11.22.33.44']
40
+ IP[ip].should be_a IP
41
+ IP[ip].object_id.should == ip.object_id
42
42
  end
43
43
 
44
44
  it "knows its integer representation" do
45
45
  i = rand(0xFFFFFFFF)
46
- IP(i).to_i.should == i
46
+ IP[i].to_i.should == i
47
47
  end
48
48
 
49
49
  it "knows its string representation" do
50
- IP('11.22.33.44').to_s.should == '11.22.33.44'
50
+ IP['11.22.33.44'].to_s.should == '11.22.33.44'
51
51
  end
52
52
 
53
- it "knows its parts" do
54
- IP('44.33.22.11').parts.should == [44, 33, 22, 11]
53
+ it "knows its octets" do
54
+ IP['44.33.22.11'].octets.should == [44, 33, 22, 11]
55
55
  end
56
56
 
57
57
  it "knows the max" do
@@ -60,18 +60,22 @@ describe IP do
60
60
  IP.max.to_s.should == '255.255.255.255'
61
61
  end
62
62
 
63
+ it "fetches a random ip" do
64
+ IP.rand.should be_a IP
65
+ end
66
+
63
67
  it "is comparable" do
64
68
  IP.included_modules.should include Comparable
65
- IP.public_methods.should include '<=>'
69
+ IP.public_methods.should include :<=>
66
70
 
67
71
  i1, i2 = rand(0xFFFFFFFF), rand(0xFFFFFFFF)
68
- (IP(i1) <=> IP(i2)).should == (i1 <=> i2)
72
+ (IP[i1] <=> IP[i2]).should == (i1 <=> i2)
69
73
  end
70
74
 
71
75
  it "can add, subtract, and succ" do
72
76
  i1, i2 = rand(0xFFFFFFF), rand(0xFFFFFFF)
73
- ip1 = IP(i1)
74
- ipsum = IP(i1) + i2
77
+ ip1 = IP[i1]
78
+ ipsum = IP[i1] + i2
75
79
  ipsum.should be_a IP
76
80
  ipsum.to_i.should == i1 + i2
77
81
 
@@ -81,15 +85,15 @@ describe IP do
81
85
  end
82
86
 
83
87
  it "knows its prefix and rest field given a netmask" do
84
- ip = IP('11.22.33.44')
88
+ ip = IP['11.22.33.44']
85
89
 
86
- ip.prefix('255.255.255.0').should == IP('11.22.33.00')
87
- ip.rest_field('255.255.255.0').should == IP('0.0.0.44')
90
+ ip.prefix('255.255.255.0').should == IP['11.22.33.00']
91
+ ip.rest_field('255.255.255.0').should == IP['0.0.0.44']
88
92
  (ip.prefix('255.255.255.0') + ip.rest_field('255.255.255.0')).
89
93
  should == ip
90
94
 
91
- ip.prefix('255.255.240.0').should == IP('11.22.32.00')
92
- ip.rest_field('255.255.240.0').should == IP('0.0.1.44')
95
+ ip.prefix('255.255.240.0').should == IP['11.22.32.00']
96
+ ip.rest_field('255.255.240.0').should == IP['0.0.1.44']
93
97
  (ip.prefix('255.255.240.0') + ip.rest_field('255.255.240.0')).
94
98
  should == ip
95
99
  end
@@ -97,10 +101,10 @@ describe IP do
97
101
  it "knows whether it's a netmask" do
98
102
  zero_bits = rand(32)
99
103
  (0..32).each do |bits|
100
- IP((0xFFFFFFFF >> bits) << bits).should be_netmask
104
+ IP[(0xFFFFFFFF >> bits) << bits].should be_netmask
101
105
  end
102
106
 
103
- IP('1.2.3.4').should_not be_netmask
104
- IP('0.255.0.0').should_not be_netmask
107
+ IP['1.2.3.4'].should_not be_netmask
108
+ IP['0.255.0.0'].should_not be_netmask
105
109
  end
106
110
  end
@@ -1,14 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Radix" do
4
- before :each do
5
- @lim = 50 + rand(100)
6
- @rad = 2 + rand(9)
7
- end
4
+ let(:lim) { 50 + rand(100) }
5
+ let(:rad) { 2 + rand(9) }
8
6
 
9
7
  it "calculates radix" do
10
- (1..@lim).each do |i|
11
- i.radix(@rad).join.should == i.to_s(@rad)
8
+ (1..lim).each do |i|
9
+ i.radix(rad).join.should == i.to_s(rad)
12
10
  end
13
11
  end
14
12
  end
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- require 'spec'
2
+ require 'rspec'
3
3
 
4
4
  require File.expand_path(File.join(
5
5
  File.dirname(__FILE__),
metadata CHANGED
@@ -1,48 +1,35 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: iplogic
3
- version: !ruby/object:Gem::Version
4
- hash: 19
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 4
10
- version: 0.1.4
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Jay Adkisson
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2010-11-13 00:00:00 -08:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2010-11-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: rspec
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &12043080 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
18
+ requirements:
27
19
  - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 15
30
- segments:
31
- - 1
32
- - 0
33
- version: "1.0"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
34
22
  type: :development
35
- version_requirements: *id001
23
+ prerelease: false
24
+ version_requirements: *12043080
36
25
  description: An IPv4 swiss-army chainsaw
37
26
  email: jay@causes.com
38
27
  executables: []
39
-
40
28
  extensions: []
41
-
42
- extra_rdoc_files:
29
+ extra_rdoc_files:
43
30
  - LICENSE
44
31
  - README.md
45
- files:
32
+ files:
46
33
  - Rakefile
47
34
  - LICENSE
48
35
  - README.md
@@ -56,41 +43,31 @@ files:
56
43
  - spec/cidr_spec.rb
57
44
  - spec/spec_helper.rb
58
45
  - spec/radix_spec.rb
59
- has_rdoc: true
60
46
  homepage: http://github.com/causes/iplogic
61
47
  licenses: []
62
-
63
48
  post_install_message:
64
49
  rdoc_options: []
65
-
66
- require_paths:
50
+ require_paths:
67
51
  - lib
68
- required_ruby_version: !ruby/object:Gem::Requirement
52
+ required_ruby_version: !ruby/object:Gem::Requirement
69
53
  none: false
70
- requirements:
71
- - - ">="
72
- - !ruby/object:Gem::Version
73
- hash: 3
74
- segments:
75
- - 0
76
- version: "0"
77
- required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
59
  none: false
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- hash: 3
83
- segments:
84
- - 0
85
- version: "0"
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
86
64
  requirements: []
87
-
88
65
  rubyforge_project:
89
- rubygems_version: 1.5.2
66
+ rubygems_version: 1.8.11
90
67
  signing_key:
91
68
  specification_version: 3
92
69
  summary: Because it's just a 32-bit integer.
93
- test_files:
70
+ test_files:
94
71
  - spec/ip_spec.rb
95
72
  - spec/cidr_spec.rb
96
73
  - spec/spec_helper.rb