Make #has_key? also indifferent in access

With the old strategy for indifferent access, one still had to use the
correct one of String or Symbol to ask if params#has_key? -- this fixes
that so that access is more truly indifferent.
This commit is contained in:
Stephen Paul Weber 2016-08-13 10:54:19 -05:00 committed by Jon Hope
parent ccd8640d89
commit ab69422e61
3 changed files with 16 additions and 7 deletions

View File

@ -240,6 +240,18 @@ module Sinatra
def http_status; 404 end
end
class IndifferentHash < Hash
def [](key)
value = super(key)
return super(key.to_s) if value.nil? && Symbol === key
value
end
def has_key?(key)
super(key) || (Symbol === key && super(key.to_s))
end
end
# Methods available to routes, before/after filters, and views.
module Helpers
# Set or retrieve the response status code.
@ -1070,7 +1082,7 @@ module Sinatra
def indifferent_params(object)
case object
when Hash
new_hash = indifferent_hash
new_hash = IndifferentHash.new
object.each { |key, value| new_hash[key] = indifferent_params(value) }
new_hash
when Array
@ -1080,11 +1092,6 @@ module Sinatra
end
end
# Creates a Hash with indifferent access.
def indifferent_hash
Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
end
# Run the block with 'throw :halt' support and apply result to the response.
def invoke
res = catch(:halt) { yield }

View File

@ -38,7 +38,7 @@ class RequestTest < Minitest::Test
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
'rack.input' => StringIO.new('foo=bar')
)
Sinatra::Base.new!.send(:indifferent_hash).replace(request.params)
Sinatra::IndifferentHash.new.replace(request.params)
dumped = Marshal.dump(request.params)
assert_equal 'bar', Marshal.load(dumped)['foo']
end

View File

@ -271,7 +271,9 @@ class RoutingTest < Minitest::Test
mock_app {
get '/:foo' do
assert_equal 'bar', params['foo']
assert params.has_key?('foo')
assert_equal 'bar', params[:foo]
assert params.has_key?(:foo)
'well, alright'
end
}