addressable 2.2.2 → 2.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.
data/CHANGELOG CHANGED
@@ -1,3 +1,6 @@
1
+ === Addressable 2.2.3
2
+ - added :flat_array notation for query strings
3
+
1
4
  === Addressable 2.2.2
2
5
  - fixed issue with percent escaping of '+' character in query strings
3
6
 
@@ -1379,7 +1379,7 @@ module Addressable
1379
1379
  # <code>:subscript</code>. The <code>:dot</code> notation is not
1380
1380
  # supported for assignment. Default value is <code>:subscript</code>.
1381
1381
  #
1382
- # @return [Hash] The query string parsed as a Hash object.
1382
+ # @return [Hash, Array] The query string parsed as a Hash or Array object.
1383
1383
  #
1384
1384
  # @example
1385
1385
  # Addressable::URI.parse("?one=1&two=2&three=3").query_values
@@ -1402,12 +1402,16 @@ module Addressable
1402
1402
  # "?one[two][three][]=four&one[two][three][]=five"
1403
1403
  # ).query_values
1404
1404
  # #=> {"one" => {"two" => {"three" => ["four", "five"]}}}
1405
+ # Addressable::URI.parse(
1406
+ # "?one=two&one=three").query_values(:notation => :flat_array)
1407
+ # #=> [['one', 'two'], ['one', 'three']]
1405
1408
  def query_values(options={})
1406
1409
  defaults = {:notation => :subscript}
1407
1410
  options = defaults.merge(options)
1408
- if ![:flat, :dot, :subscript].include?(options[:notation])
1411
+ if ![:flat, :dot, :subscript, :flat_array].include?(options[:notation])
1409
1412
  raise ArgumentError,
1410
- "Invalid notation. Must be one of: [:flat, :dot, :subscript]."
1413
+ "Invalid notation. Must be one of: " +
1414
+ "[:flat, :dot, :subscript, :flat_array]."
1411
1415
  end
1412
1416
  dehash = lambda do |hash|
1413
1417
  hash.each do |(key, value)|
@@ -1424,9 +1428,10 @@ module Addressable
1424
1428
  end
1425
1429
  end
1426
1430
  return nil if self.query == nil
1431
+ empty_accumulator = :flat_array == options[:notation] ? [] : {}
1427
1432
  return ((self.query.split("&").map do |pair|
1428
1433
  pair.split("=", -1) if pair && pair != ""
1429
- end).compact.inject({}) do |accumulator, (key, value)|
1434
+ end).compact.inject(empty_accumulator.dup) do |accumulator, (key, value)|
1430
1435
  value = true if value.nil?
1431
1436
  key = self.class.unencode_component(key)
1432
1437
  if value != true
@@ -1437,6 +1442,8 @@ module Addressable
1437
1442
  raise ArgumentError, "Key was repeated: #{key.inspect}"
1438
1443
  end
1439
1444
  accumulator[key] = value
1445
+ elsif options[:notation] == :flat_array
1446
+ accumulator << [key, value]
1440
1447
  else
1441
1448
  if options[:notation] == :dot
1442
1449
  array_value = false
@@ -1459,8 +1466,12 @@ module Addressable
1459
1466
  end
1460
1467
  end
1461
1468
  accumulator
1462
- end).inject({}) do |accumulator, (key, value)|
1463
- accumulator[key] = value.kind_of?(Hash) ? dehash.call(value) : value
1469
+ end).inject(empty_accumulator.dup) do |accumulator, (key, value)|
1470
+ if options[:notation] == :flat_array
1471
+ accumulator << [key, value]
1472
+ else
1473
+ accumulator[key] = value.kind_of?(Hash) ? dehash.call(value) : value
1474
+ end
1464
1475
  accumulator
1465
1476
  end
1466
1477
  end
@@ -1470,7 +1481,7 @@ module Addressable
1470
1481
  # This method produces a query string using the :subscript notation.
1471
1482
  # An empty Hash will result in a nil query.
1472
1483
  #
1473
- # @param [Hash, #to_hash] new_query_values The new query values.
1484
+ # @param [Hash, #to_hash, Array] new_query_values The new query values.
1474
1485
  def query_values=(new_query_values)
1475
1486
  # Check for frozenness
1476
1487
  raise TypeError, "Can't modify frozen URI." if self.frozen?
@@ -1478,15 +1489,22 @@ module Addressable
1478
1489
  self.query = nil
1479
1490
  return nil
1480
1491
  end
1481
- if !new_query_values.respond_to?(:to_hash)
1482
- raise TypeError, "Can't convert #{new_query_values.class} into Hash."
1483
- end
1484
- new_query_values = new_query_values.to_hash
1485
- new_query_values = new_query_values.map do |key, value|
1486
- key = key.to_s if key.kind_of?(Symbol)
1487
- [key, value]
1492
+
1493
+ if !new_query_values.is_a?(Array)
1494
+ if !new_query_values.respond_to?(:to_hash)
1495
+ raise TypeError,
1496
+ "Can't convert #{new_query_values.class} into Hash."
1497
+ end
1498
+ new_query_values = new_query_values.to_hash
1499
+ new_query_values = new_query_values.map do |key, value|
1500
+ key = key.to_s if key.kind_of?(Symbol)
1501
+ [key, value]
1502
+ end
1503
+ # Useful default for OAuth and caching.
1504
+ # Only to be used for non-Array inputs. Arrays should preserve order.
1505
+ new_query_values.sort!
1488
1506
  end
1489
- new_query_values.sort! # Useful default for OAuth and caching
1507
+ # new_query_values have form [['key1', 'value1'], ['key2', 'value2']]
1490
1508
 
1491
1509
  # Algorithm shamelessly stolen from Julien Genestoux, slightly modified
1492
1510
  buffer = ""
@@ -28,7 +28,7 @@ if !defined?(Addressable::VERSION)
28
28
  module VERSION #:nodoc:
29
29
  MAJOR = 2
30
30
  MINOR = 2
31
- TINY = 2
31
+ TINY = 3
32
32
 
33
33
  STRING = [MAJOR, MINOR, TINY].join('.')
34
34
  end
@@ -3056,6 +3056,12 @@ describe Addressable::URI, "when parsed from '?one=1&two=2&three=3'" do
3056
3056
  @uri.query_values(:notation => :bogus)
3057
3057
  end).should raise_error(ArgumentError)
3058
3058
  end
3059
+
3060
+ it "should have the correct flat array notation query values" do
3061
+ @uri.query_values(:notation => :flat_array).should == [
3062
+ ["one", "1"], ["two", "2"], ["three", "3"]
3063
+ ]
3064
+ end
3059
3065
  end
3060
3066
 
3061
3067
  describe Addressable::URI, "when parsed from '?one[two][three]=four'" do
@@ -3072,6 +3078,12 @@ describe Addressable::URI, "when parsed from '?one[two][three]=four'" do
3072
3078
  "one[two][three]" => "four"
3073
3079
  }
3074
3080
  end
3081
+
3082
+ it "should have the correct flat array notation query values" do
3083
+ @uri.query_values(:notation => :flat_array).should == [
3084
+ ["one[two][three]", "four"]
3085
+ ]
3086
+ end
3075
3087
  end
3076
3088
 
3077
3089
  describe Addressable::URI, "when parsed from '?one.two.three=four'" do
@@ -3090,6 +3102,12 @@ describe Addressable::URI, "when parsed from '?one.two.three=four'" do
3090
3102
  "one.two.three" => "four"
3091
3103
  }
3092
3104
  end
3105
+
3106
+ it "should have the correct flat array notation query values" do
3107
+ @uri.query_values(:notation => :flat_array).should == [
3108
+ ["one.two.three", "four"]
3109
+ ]
3110
+ end
3093
3111
  end
3094
3112
 
3095
3113
  describe Addressable::URI, "when parsed from " +
@@ -3110,6 +3128,12 @@ describe Addressable::URI, "when parsed from " +
3110
3128
  "one[two][five]" => "six"
3111
3129
  }
3112
3130
  end
3131
+
3132
+ it "should have the correct flat array notation query values" do
3133
+ @uri.query_values(:notation => :flat_array).should == [
3134
+ ["one[two][three]", "four"], ["one[two][five]", "six"]
3135
+ ]
3136
+ end
3113
3137
  end
3114
3138
 
3115
3139
  describe Addressable::URI, "when parsed from " +
@@ -3130,6 +3154,26 @@ describe Addressable::URI, "when parsed from " +
3130
3154
  "one.two.five" => "six"
3131
3155
  }
3132
3156
  end
3157
+
3158
+ it "should have the correct flat array notation query values" do
3159
+ @uri.query_values(:notation => :flat_array).should == [
3160
+ ["one.two.three", "four"], ["one.two.five", "six"]
3161
+ ]
3162
+ end
3163
+ end
3164
+
3165
+ describe Addressable::URI, "when parsed from " +
3166
+ "'?one=two&one=three'" do
3167
+ before do
3168
+ @uri = Addressable::URI.parse(
3169
+ "?one=two&one=three"
3170
+ )
3171
+ end
3172
+
3173
+ it "should have correct flat_array notation query values" do
3174
+ @uri.query_values(:notation => :flat_array).should ==
3175
+ [['one', 'two'], ['one', 'three']]
3176
+ end
3133
3177
  end
3134
3178
 
3135
3179
  describe Addressable::URI, "when parsed from " +
@@ -3151,6 +3195,13 @@ describe Addressable::URI, "when parsed from " +
3151
3195
  @uri.query_values(:notation => :flat)
3152
3196
  end).should raise_error(ArgumentError)
3153
3197
  end
3198
+
3199
+ it "should not raise an error if a key is " +
3200
+ "repeated in the flat array notation" do
3201
+ (lambda do
3202
+ @uri.query_values(:notation => :flat_array)
3203
+ end).should_not raise_error
3204
+ end
3154
3205
  end
3155
3206
 
3156
3207
  describe Addressable::URI, "when parsed from " +
@@ -3168,6 +3219,36 @@ describe Addressable::URI, "when parsed from " +
3168
3219
  end
3169
3220
  end
3170
3221
 
3222
+ describe Addressable::URI, "when parsed from " +
3223
+ "'?one[two][three][1]=four&one[two][three][0]=five'" do
3224
+ before do
3225
+ @uri = Addressable::URI.parse(
3226
+ "?one[two][three][1]=four&one[two][three][0]=five"
3227
+ )
3228
+ end
3229
+
3230
+ it "should have the correct subscript notation query values" do
3231
+ @uri.query_values(:notation => :subscript).should == {
3232
+ "one" => {"two" => {"three" => ["five", "four"]}}
3233
+ }
3234
+ end
3235
+ end
3236
+
3237
+ describe Addressable::URI, "when parsed from " +
3238
+ "'?one[two][three][2]=four&one[two][three][1]=five'" do
3239
+ before do
3240
+ @uri = Addressable::URI.parse(
3241
+ "?one[two][three][2]=four&one[two][three][1]=five"
3242
+ )
3243
+ end
3244
+
3245
+ it "should have the correct subscript notation query values" do
3246
+ @uri.query_values(:notation => :subscript).should == {
3247
+ "one" => {"two" => {"three" => ["five", "four"]}}
3248
+ }
3249
+ end
3250
+ end
3251
+
3171
3252
  describe Addressable::URI, "when parsed from " +
3172
3253
  "'http://www.詹姆斯.com/'" do
3173
3254
  before do
@@ -4183,6 +4264,21 @@ describe Addressable::URI, "when assigning query values" do
4183
4264
  @uri.query_values = {'ab' => 'c', :ab => 'a', :a => 'x'}
4184
4265
  @uri.query.should == "a=x&ab=a&ab=c"
4185
4266
  end
4267
+
4268
+ it "should correctly assign " +
4269
+ "[['b', 'c'], ['b', 'a'], ['a', 'a']]" do
4270
+ # Order can be guaranteed in this format, so preserve it.
4271
+ @uri.query_values = [['b', 'c'], ['b', 'a'], ['a', 'a']]
4272
+ @uri.query.should == "b=c&b=a&a=a"
4273
+ end
4274
+
4275
+ it "should preserve query string order" do
4276
+ query_string = (('a'..'z').to_a.shuffle.map { |e| "#{e}=#{e}" }).join("&")
4277
+ @uri.query = query_string
4278
+ original_uri = @uri.to_s
4279
+ @uri.query_values = @uri.query_values(:notation => :flat_array)
4280
+ @uri.to_s.should == original_uri
4281
+ end
4186
4282
  end
4187
4283
 
4188
4284
  describe Addressable::URI, "when assigning path values" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: addressable
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
5
- prerelease: false
4
+ hash: 1
5
+ prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 2
9
- - 2
10
- version: 2.2.2
9
+ - 3
10
+ version: 2.2.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bob Aman
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-12 00:00:00 -07:00
18
+ date: 2011-01-20 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -146,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
146
  requirements: []
147
147
 
148
148
  rubyforge_project: addressable
149
- rubygems_version: 1.3.7
149
+ rubygems_version: 1.4.1
150
150
  signing_key:
151
151
  specification_version: 3
152
152
  summary: URI Implementation