pg 1.1.4 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/ChangeLog +0 -6595
  5. data/History.rdoc +86 -0
  6. data/Manifest.txt +3 -2
  7. data/README-Windows.rdoc +4 -4
  8. data/README.ja.rdoc +1 -2
  9. data/README.rdoc +44 -9
  10. data/Rakefile +8 -6
  11. data/Rakefile.cross +57 -56
  12. data/ext/errorcodes.def +64 -0
  13. data/ext/errorcodes.txt +18 -2
  14. data/ext/extconf.rb +6 -6
  15. data/ext/pg.c +132 -95
  16. data/ext/pg.h +21 -18
  17. data/ext/pg_binary_decoder.c +9 -9
  18. data/ext/pg_binary_encoder.c +13 -12
  19. data/ext/pg_coder.c +21 -9
  20. data/ext/pg_connection.c +388 -298
  21. data/ext/pg_copy_coder.c +6 -3
  22. data/ext/pg_record_coder.c +491 -0
  23. data/ext/pg_result.c +279 -127
  24. data/ext/pg_text_decoder.c +14 -8
  25. data/ext/pg_text_encoder.c +180 -48
  26. data/ext/pg_tuple.c +14 -6
  27. data/ext/pg_type_map.c +1 -1
  28. data/ext/pg_type_map_all_strings.c +4 -4
  29. data/ext/pg_type_map_by_class.c +9 -4
  30. data/ext/pg_type_map_by_column.c +7 -6
  31. data/ext/pg_type_map_by_mri_type.c +1 -1
  32. data/ext/pg_type_map_by_oid.c +3 -2
  33. data/ext/pg_type_map_in_ruby.c +1 -1
  34. data/ext/{util.c → pg_util.c} +5 -5
  35. data/ext/{util.h → pg_util.h} +0 -0
  36. data/lib/pg.rb +4 -4
  37. data/lib/pg/basic_type_mapping.rb +81 -18
  38. data/lib/pg/binary_decoder.rb +1 -0
  39. data/lib/pg/coder.rb +22 -1
  40. data/lib/pg/connection.rb +2 -2
  41. data/lib/pg/constants.rb +1 -0
  42. data/lib/pg/exceptions.rb +1 -0
  43. data/lib/pg/result.rb +13 -1
  44. data/lib/pg/text_decoder.rb +2 -3
  45. data/lib/pg/text_encoder.rb +8 -18
  46. data/lib/pg/type_map_by_column.rb +2 -1
  47. data/spec/helpers.rb +11 -11
  48. data/spec/pg/basic_type_mapping_spec.rb +140 -18
  49. data/spec/pg/connection_spec.rb +166 -89
  50. data/spec/pg/result_spec.rb +194 -4
  51. data/spec/pg/tuple_spec.rb +55 -2
  52. data/spec/pg/type_map_by_class_spec.rb +1 -1
  53. data/spec/pg/type_map_by_column_spec.rb +5 -1
  54. data/spec/pg/type_map_by_oid_spec.rb +2 -2
  55. data/spec/pg/type_spec.rb +180 -6
  56. metadata +31 -30
  57. metadata.gz.sig +0 -0
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pg' unless defined?( PG )
4
5
  require 'uri'
@@ -47,7 +48,7 @@ class PG::Connection
47
48
 
48
49
  if args.length == 1
49
50
  case args.first
50
- when URI, /\A#{URI.regexp}\z/
51
+ when URI, /\A#{URI::ABS_URI_REF}\z/
51
52
  uri = URI(args.first)
52
53
  options.merge!( Hash[URI.decode_www_form( uri.query )] ) if uri.query
53
54
  when /=/
@@ -288,4 +289,3 @@ class PG::Connection
288
289
  # pg-1.1.0+ defaults to libpq's async API for query related blocking methods
289
290
  self.async_api = true
290
291
  end # class PG::Connection
291
-
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pg' unless defined?( PG )
4
5
 
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pg' unless defined?( PG )
4
5
 
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pg' unless defined?( PG )
4
5
 
@@ -9,12 +10,23 @@ class PG::Result
9
10
  #
10
11
  # +type_map+: a PG::TypeMap instance.
11
12
  #
12
- # See PG::BasicTypeMapForResults
13
+ # This method is equal to #type_map= , but returns self, so that calls can be chained.
14
+ #
15
+ # See also PG::BasicTypeMapForResults
13
16
  def map_types!(type_map)
14
17
  self.type_map = type_map
15
18
  return self
16
19
  end
17
20
 
21
+ # Set the data type for all field name returning methods.
22
+ #
23
+ # +type+: a Symbol defining the field name type.
24
+ #
25
+ # This method is equal to #field_name_type= , but returns self, so that calls can be chained.
26
+ def field_names_as(type)
27
+ self.field_name_type = type
28
+ return self
29
+ end
18
30
 
19
31
  ### Return a String representation of the object suitable for debugging.
20
32
  def inspect
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'date'
4
5
  require 'json'
@@ -6,10 +7,8 @@ require 'json'
6
7
  module PG
7
8
  module TextDecoder
8
9
  class Date < SimpleDecoder
9
- ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
10
-
11
10
  def decode(string, tuple=nil, field=nil)
12
- if string =~ ISO_DATE
11
+ if string =~ /\A(\d{4})-(\d\d)-(\d\d)\z/
13
12
  ::Date.new $1.to_i, $2.to_i, $3.to_i
14
13
  else
15
14
  string
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'json'
4
5
  require 'ipaddr'
@@ -6,36 +7,26 @@ require 'ipaddr'
6
7
  module PG
7
8
  module TextEncoder
8
9
  class Date < SimpleEncoder
9
- STRFTIME_ISO_DATE = "%Y-%m-%d".freeze
10
10
  def encode(value)
11
- value.respond_to?(:strftime) ? value.strftime(STRFTIME_ISO_DATE) : value
11
+ value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d") : value
12
12
  end
13
13
  end
14
14
 
15
15
  class TimestampWithoutTimeZone < SimpleEncoder
16
- STRFTIME_ISO_DATETIME_WITHOUT_TIMEZONE = "%Y-%m-%d %H:%M:%S.%N".freeze
17
16
  def encode(value)
18
- value.respond_to?(:strftime) ? value.strftime(STRFTIME_ISO_DATETIME_WITHOUT_TIMEZONE) : value
17
+ value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d %H:%M:%S.%N") : value
19
18
  end
20
19
  end
21
20
 
22
21
  class TimestampUtc < SimpleEncoder
23
- STRFTIME_ISO_DATETIME_WITHOUT_TIMEZONE_UTC = "%Y-%m-%d %H:%M:%S.%N".freeze
24
22
  def encode(value)
25
- value.respond_to?(:utc) ? value.utc.strftime(STRFTIME_ISO_DATETIME_WITHOUT_TIMEZONE_UTC) : value
23
+ value.respond_to?(:utc) ? value.utc.strftime("%Y-%m-%d %H:%M:%S.%N") : value
26
24
  end
27
25
  end
28
26
 
29
27
  class TimestampWithTimeZone < SimpleEncoder
30
- STRFTIME_ISO_DATETIME_WITH_TIMEZONE = "%Y-%m-%d %H:%M:%S.%N %:z".freeze
31
28
  def encode(value)
32
- value.respond_to?(:strftime) ? value.strftime(STRFTIME_ISO_DATETIME_WITH_TIMEZONE) : value
33
- end
34
- end
35
-
36
- class Numeric < SimpleEncoder
37
- def encode(value)
38
- value.is_a?(BigDecimal) ? value.to_s('F') : value
29
+ value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d %H:%M:%S.%N %:z") : value
39
30
  end
40
31
  end
41
32
 
@@ -51,12 +42,12 @@ module PG
51
42
  when IPAddr
52
43
  default_prefix = (value.family == Socket::AF_INET ? 32 : 128)
53
44
  s = value.to_s
54
- if value.respond_to?(:prefix)
45
+ if value.respond_to?(:prefix)
55
46
  prefix = value.prefix
56
- else
47
+ else
57
48
  range = value.to_range
58
49
  prefix = default_prefix - Math.log(((range.end.to_i - range.begin.to_i) + 1), 2).to_i
59
- end
50
+ end
60
51
  s << "/" << prefix.to_s if prefix != default_prefix
61
52
  s
62
53
  else
@@ -66,4 +57,3 @@ module PG
66
57
  end
67
58
  end
68
59
  end # module PG
69
-
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pg' unless defined?( PG )
4
5
 
@@ -9,7 +10,7 @@ class PG::TypeMapByColumn
9
10
  end
10
11
 
11
12
  def inspect
12
- type_strings = coders.map{|c| c ? "#{c.name}:#{c.format}" : 'nil' }
13
+ type_strings = coders.map{|c| c ? c.inspect_short : 'nil' }
13
14
  "#<#{self.class} #{type_strings.join(' ')}>"
14
15
  end
15
16
  end
@@ -172,18 +172,18 @@ module PG::TestingHelpers
172
172
  datadir = testdir + 'data'
173
173
  pidfile = datadir + 'postmaster.pid'
174
174
  if pidfile.exist? && pid = pidfile.read.chomp.to_i
175
- $stderr.puts "pidfile (%p) exists: %d" % [ pidfile, pid ]
175
+ trace "pidfile (%p) exists: %d" % [ pidfile, pid ]
176
176
  begin
177
177
  Process.kill( 0, pid )
178
178
  rescue Errno::ESRCH
179
- $stderr.puts "No postmaster running for %s" % [ datadir ]
179
+ trace "No postmaster running for %s" % [ datadir ]
180
180
  # Process isn't alive, so don't try to stop it
181
181
  else
182
- $stderr.puts "Stopping lingering database at PID %d" % [ pid ]
182
+ trace "Stopping lingering database at PID %d" % [ pid ]
183
183
  run 'pg_ctl', '-D', datadir.to_s, '-m', 'fast', 'stop'
184
184
  end
185
185
  else
186
- $stderr.puts "No pidfile (%p)" % [ pidfile ]
186
+ trace "No pidfile (%p)" % [ pidfile ]
187
187
  end
188
188
  end
189
189
  end
@@ -194,7 +194,7 @@ module PG::TestingHelpers
194
194
  require 'pg'
195
195
  stop_existing_postmasters()
196
196
 
197
- puts "Setting up test database for #{description}"
197
+ trace "Setting up test database for #{description}"
198
198
  @test_pgdata = TEST_DIRECTORY + 'data'
199
199
  @test_pgdata.mkpath
200
200
 
@@ -209,7 +209,7 @@ module PG::TestingHelpers
209
209
  begin
210
210
  unless (@test_pgdata+"postgresql.conf").exist?
211
211
  FileUtils.rm_rf( @test_pgdata, :verbose => $DEBUG )
212
- $stderr.puts "Running initdb"
212
+ trace "Running initdb"
213
213
  log_and_run @logfile, 'initdb', '-E', 'UTF8', '--no-locale', '-D', @test_pgdata.to_s
214
214
  end
215
215
 
@@ -218,14 +218,14 @@ module PG::TestingHelpers
218
218
  '-D', @test_pgdata.to_s, 'start'
219
219
  sleep 2
220
220
 
221
- $stderr.puts "Creating the test DB"
221
+ trace "Creating the test DB"
222
222
  log_and_run @logfile, 'psql', '-e', '-c', 'DROP DATABASE IF EXISTS test', 'postgres'
223
223
  log_and_run @logfile, 'createdb', '-e', 'test'
224
224
 
225
225
  rescue => err
226
226
  $stderr.puts "%p during test setup: %s" % [ err.class, err.message ]
227
227
  $stderr.puts "See #{@logfile} for details."
228
- $stderr.puts *err.backtrace if $DEBUG
228
+ $stderr.puts err.backtrace if $DEBUG
229
229
  fail
230
230
  end
231
231
 
@@ -239,7 +239,7 @@ module PG::TestingHelpers
239
239
 
240
240
 
241
241
  def teardown_testing_db( conn )
242
- puts "Tearing down test database"
242
+ trace "Tearing down test database"
243
243
 
244
244
  if conn
245
245
  check_for_lingering_connections( conn )
@@ -370,11 +370,11 @@ RSpec.configure do |config|
370
370
  else
371
371
  config.filter_run_excluding :windows
372
372
  end
373
- config.filter_run_excluding :socket_io unless
374
- PG::Connection.instance_methods.map( &:to_sym ).include?( :socket_io )
375
373
 
376
374
  config.filter_run_excluding( :postgresql_93 ) if PG.library_version < 90300
377
375
  config.filter_run_excluding( :postgresql_94 ) if PG.library_version < 90400
378
376
  config.filter_run_excluding( :postgresql_95 ) if PG.library_version < 90500
377
+ config.filter_run_excluding( :postgresql_96 ) if PG.library_version < 90600
379
378
  config.filter_run_excluding( :postgresql_10 ) if PG.library_version < 100000
379
+ config.filter_run_excluding( :postgresql_12 ) if PG.library_version < 120000
380
380
  end
@@ -32,8 +32,8 @@ describe 'Basic type mapping' do
32
32
  # Encoding Examples
33
33
  #
34
34
 
35
- it "should do basic param encoding", :ruby_19 do
36
- res = @conn.exec_params( "SELECT $1::int8,$2::float,$3,$4::TEXT",
35
+ it "should do basic param encoding" do
36
+ res = @conn.exec_params( "SELECT $1::int8, $2::float, $3, $4::TEXT",
37
37
  [1, 2.1, true, "b"], nil, basic_type_mapping )
38
38
 
39
39
  expect( res.values ).to eq( [
@@ -43,20 +43,126 @@ describe 'Basic type mapping' do
43
43
  expect( result_typenames(res) ).to eq( ['bigint', 'double precision', 'boolean', 'text'] )
44
44
  end
45
45
 
46
- it "should do array param encoding" do
47
- res = @conn.exec_params( "SELECT $1,$2,$3,$4", [
48
- [1, 2, 3], [[1, 2], [3, nil]],
49
- [1.11, 2.21],
50
- ['/,"'.gsub("/", "\\"), nil, 'abcäöü'],
46
+ it "should do basic Time encoding" do
47
+ res = @conn.exec_params( "SELECT $1 AT TIME ZONE '-02'",
48
+ [Time.new(2019, 12, 8, 20, 38, 12.123, "-01:00")], nil, basic_type_mapping )
49
+
50
+ expect( res.values ).to eq( [[ "2019-12-08 23:38:12.123" ]] )
51
+ end
52
+
53
+ it "should do basic param encoding of various float values" do
54
+ res = @conn.exec_params( "SELECT $1::float, $2::float, $3::float, $4::float, $5::float, $6::float, $7::float, $8::float, $9::float, $10::float, $11::float, $12::float",
55
+ [0, 7, 9, 0.1, 0.9, -0.11, 10.11,
56
+ 9876543210987654321e-400,
57
+ 9876543210987654321e400,
58
+ -1.234567890123456789e-280,
59
+ -1.234567890123456789e280,
60
+ 9876543210987654321e280
61
+ ], nil, basic_type_mapping )
62
+
63
+ expect( res.values[0][0, 9] ).to eq(
64
+ [ "0", "7", "9", "0.1", "0.9", "-0.11", "10.11", "0", "Infinity" ]
65
+ )
66
+
67
+ expect( res.values[0][9] ).to match( /^-1\.2345678901234\d*e\-280$/ )
68
+ expect( res.values[0][10] ).to match( /^-1\.2345678901234\d*e\+280$/ )
69
+ expect( res.values[0][11] ).to match( /^9\.8765432109876\d*e\+298$/ )
70
+
71
+ expect( result_typenames(res) ).to eq( ['double precision'] * 12 )
72
+ end
73
+
74
+ it "should do default array-as-array param encoding" do
75
+ expect( basic_type_mapping.encode_array_as).to eq(:array)
76
+ res = @conn.exec_params( "SELECT $1,$2,$3,$4,$5,$6", [
77
+ [1, 2, 3], # Integer -> bigint[]
78
+ [[1, 2], [3, nil]], # Integer two dimensions -> bigint[]
79
+ [1.11, 2.21], # Float -> double precision[]
80
+ ['/,"'.gsub("/", "\\"), nil, 'abcäöü'], # String -> text[]
81
+ [BigDecimal("123.45")], # BigDecimal -> numeric[]
82
+ [IPAddr.new('1234::5678')], # IPAddr -> inet[]
51
83
  ], nil, basic_type_mapping )
52
84
 
53
85
  expect( res.values ).to eq( [[
54
- '{1,2,3}', '{{1,2},{3,NULL}}',
86
+ '{1,2,3}',
87
+ '{{1,2},{3,NULL}}',
55
88
  '{1.11,2.21}',
56
89
  '{"//,/"",NULL,abcäöü}'.gsub("/", "\\"),
90
+ '{123.45}',
91
+ '{1234::5678}',
92
+ ]] )
93
+
94
+ expect( result_typenames(res) ).to eq( ['bigint[]', 'bigint[]', 'double precision[]', 'text[]', 'numeric[]', 'inet[]'] )
95
+ end
96
+
97
+ it "should do default array-as-array param encoding with Time objects" do
98
+ res = @conn.exec_params( "SELECT $1", [
99
+ [Time.new(2019, 12, 8, 20, 38, 12.123, "-01:00")], # Time -> timestamptz[]
100
+ ], nil, basic_type_mapping )
101
+
102
+ expect( res.values[0][0] ).to match( /\{\"2019-12-08 \d\d:38:12.123[+-]\d\d\"\}/ )
103
+ expect( result_typenames(res) ).to eq( ['timestamp with time zone[]'] )
104
+ end
105
+
106
+ it "should do array-as-json encoding" do
107
+ basic_type_mapping.encode_array_as = :json
108
+ expect( basic_type_mapping.encode_array_as).to eq(:json)
109
+
110
+ res = @conn.exec_params( "SELECT $1::JSON, $2::JSON", [
111
+ [1, {a: 5}, true, ["a", 2], [3.4, nil]],
112
+ ['/,"'.gsub("/", "\\"), nil, 'abcäöü'],
113
+ ], nil, basic_type_mapping )
114
+
115
+ expect( res.values ).to eq( [[
116
+ '[1,{"a":5},true,["a",2],[3.4,null]]',
117
+ '["//,/"",null,"abcäöü"]'.gsub("/", "\\"),
57
118
  ]] )
58
119
 
59
- expect( result_typenames(res) ).to eq( ['bigint[]', 'bigint[]', 'double precision[]', 'text[]'] )
120
+ expect( result_typenames(res) ).to eq( ['json', 'json'] )
121
+ end
122
+
123
+ it "should do hash-as-json encoding" do
124
+ res = @conn.exec_params( "SELECT $1::JSON, $2::JSON", [
125
+ {a: 5, b: ["a", 2], c: nil},
126
+ {qu: '/,"'.gsub("/", "\\"), ni: nil, uml: 'abcäöü'},
127
+ ], nil, basic_type_mapping )
128
+
129
+ expect( res.values ).to eq( [[
130
+ '{"a":5,"b":["a",2],"c":null}',
131
+ '{"qu":"//,/"","ni":null,"uml":"abcäöü"}'.gsub("/", "\\"),
132
+ ]] )
133
+
134
+ expect( result_typenames(res) ).to eq( ['json', 'json'] )
135
+ end
136
+
137
+ describe "Record encoding" do
138
+ before :all do
139
+ @conn.exec("CREATE TYPE test_record1 AS (i int, d float, t text)")
140
+ @conn.exec("CREATE TYPE test_record2 AS (i int, r test_record1)")
141
+ end
142
+
143
+ after :all do
144
+ @conn.exec("DROP TYPE IF EXISTS test_record2 CASCADE")
145
+ @conn.exec("DROP TYPE IF EXISTS test_record1 CASCADE")
146
+ end
147
+
148
+ it "should do array-as-record encoding" do
149
+ basic_type_mapping.encode_array_as = :record
150
+ expect( basic_type_mapping.encode_array_as).to eq(:record)
151
+
152
+ res = @conn.exec_params( "SELECT $1::test_record1, $2::test_record2, $3::text", [
153
+ [5, 3.4, "txt"],
154
+ [1, [2, 4.5, "bcd"]],
155
+ [4, 5, 6],
156
+ ], nil, basic_type_mapping )
157
+
158
+ expect( res.values ).to eq( [[
159
+ '(5,3.4,txt)',
160
+ '(1,"(2,4.5,bcd)")',
161
+ '("4","5","6")',
162
+ ]] )
163
+
164
+ expect( result_typenames(res) ).to eq( ['test_record1', 'test_record2', 'text'] )
165
+ end
60
166
  end
61
167
 
62
168
  it "should do bigdecimal param encoding" do
@@ -82,6 +188,23 @@ describe 'Basic type mapping' do
82
188
  expect( result_typenames(res) ).to eq( ['inet', 'inet', 'cidr', 'cidr'] )
83
189
  end
84
190
 
191
+ it "should do array of string encoding on unknown classes" do
192
+ iv = Class.new do
193
+ def to_s
194
+ "abc"
195
+ end
196
+ end.new
197
+ res = @conn.exec_params( "SELECT $1", [
198
+ [iv, iv], # Unknown -> text[]
199
+ ], nil, basic_type_mapping )
200
+
201
+ expect( res.values ).to eq( [[
202
+ '{abc,abc}',
203
+ ]] )
204
+
205
+ expect( result_typenames(res) ).to eq( ['text[]'] )
206
+ end
207
+
85
208
  end
86
209
 
87
210
 
@@ -95,7 +218,7 @@ describe 'Basic type mapping' do
95
218
  # Decoding Examples
96
219
  #
97
220
 
98
- it "should do OID based type conversions", :ruby_19 do
221
+ it "should do OID based type conversions" do
99
222
  res = @conn.exec( "SELECT 1, 'a', 2.0::FLOAT, TRUE, '2013-06-30'::DATE, generate_series(4,5)" )
100
223
  expect( res.map_types!(basic_type_mapping).values ).to eq( [
101
224
  [ 1, 'a', 2.0, true, Date.new(2013,6,30), 4 ],
@@ -366,7 +489,6 @@ describe 'Basic type mapping' do
366
489
  sql_vals = vals.map{|v| "CAST('#{v}' AS inet)"}
367
490
  res = @conn.exec_params(("SELECT " + sql_vals.join(', ')), [], format )
368
491
  vals.each_with_index do |v, i|
369
- val = res.getvalue(0,i)
370
492
  expect( res.getvalue(0,i) ).to eq( IPAddr.new(v) )
371
493
  end
372
494
  end
@@ -390,22 +512,22 @@ describe 'Basic type mapping' do
390
512
  sql_vals = vals.map { |v| "CAST('#{v}' AS cidr)" }
391
513
  res = @conn.exec_params(("SELECT " + sql_vals.join(', ')), [], format )
392
514
  vals.each_with_index do |v, i|
393
- val = res.getvalue(0,i)
515
+ val = res.getvalue(0,i)
394
516
  ip, prefix = v.split('/', 2)
395
- expect( val.to_s ).to eq( ip )
517
+ expect( val.to_s ).to eq( ip )
396
518
  if val.respond_to?(:prefix)
397
519
  val_prefix = val.prefix
398
520
  else
399
- default_prefix = (val.family == Socket::AF_INET ? 32 : 128)
521
+ default_prefix = (val.family == Socket::AF_INET ? 32 : 128)
400
522
  range = val.to_range
401
523
  val_prefix = default_prefix - Math.log(((range.end.to_i - range.begin.to_i) + 1), 2).to_i
402
524
  end
403
525
  if v.include?('/')
404
- expect( val_prefix ).to eq( prefix.to_i )
526
+ expect( val_prefix ).to eq( prefix.to_i )
405
527
  elsif v.include?('.')
406
- expect( val_prefix ).to eq( 32 )
407
- else
408
- expect( val_prefix ).to eq( 128 )
528
+ expect( val_prefix ).to eq( 32 )
529
+ else
530
+ expect( val_prefix ).to eq( 128 )
409
531
  end
410
532
  end
411
533
  end