pg 1.1.4 → 1.2.3

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.
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