Update key conversion extensions
Fixing collision with ActiveSupport ActiveSupport implementation is not recursive
This commit is contained in:
parent
60b8e803d0
commit
ea2076ba6c
|
@ -1,5 +1,6 @@
|
|||
## Next
|
||||
|
||||
* [#247](https://github.com/intridea/hashie/pull/247): Fixed #stringify_keys and #symbolize_keys collision with ActiveSupport - [@bartoszkopinski](https://github.com/bartoszkopinski).
|
||||
* Your contribution here.
|
||||
|
||||
## 3.3.2 (11/26/2014)
|
||||
|
|
|
@ -8,10 +8,7 @@ module Hashie
|
|||
# test.stringify_keys!
|
||||
# test # => {'abc' => 'def'}
|
||||
def stringify_keys!
|
||||
keys.each do |k|
|
||||
stringify_keys_recursively!(self[k])
|
||||
self[k.to_s] = delete(k)
|
||||
end
|
||||
_stringify_keys!(self)
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -25,24 +22,23 @@ module Hashie
|
|||
|
||||
# Stringify all keys recursively within nested
|
||||
# hashes and arrays.
|
||||
def stringify_keys_recursively!(object)
|
||||
if self.class === object
|
||||
def _stringify_keys_recursively!(object)
|
||||
case object
|
||||
when self.class
|
||||
object.stringify_keys!
|
||||
elsif ::Array === object
|
||||
when ::Array
|
||||
object.each do |i|
|
||||
stringify_keys_recursively!(i)
|
||||
_stringify_keys_recursively!(i)
|
||||
end
|
||||
object
|
||||
elsif object.respond_to?(:stringify_keys!)
|
||||
object.stringify_keys!
|
||||
elsif ::Hash === object
|
||||
object.keys.each do |k|
|
||||
stringify_keys_recursively!(object[k])
|
||||
object[k.to_s] = object.delete(k)
|
||||
end
|
||||
object
|
||||
else
|
||||
object
|
||||
when ::Hash
|
||||
_stringify_keys!(object)
|
||||
end
|
||||
end
|
||||
|
||||
def _stringify_keys!(hash)
|
||||
hash.keys.each do |k|
|
||||
_stringify_keys_recursively!(hash[k])
|
||||
hash[k.to_s] = hash.delete(k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,10 +8,7 @@ module Hashie
|
|||
# test.symbolize_keys!
|
||||
# test # => {:abc => 'def'}
|
||||
def symbolize_keys!
|
||||
keys.each do |k|
|
||||
symbolize_keys_recursively!(self[k])
|
||||
self[k.to_sym] = delete(k)
|
||||
end
|
||||
_symbolize_keys!(self)
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -25,18 +22,23 @@ module Hashie
|
|||
|
||||
# Symbolize all keys recursively within nested
|
||||
# hashes and arrays.
|
||||
def symbolize_keys_recursively!(object)
|
||||
if self.class === object
|
||||
def _symbolize_keys_recursively!(object)
|
||||
case object
|
||||
when self.class
|
||||
object.symbolize_keys!
|
||||
elsif ::Array === object
|
||||
when ::Array
|
||||
object.each do |i|
|
||||
symbolize_keys_recursively!(i)
|
||||
_symbolize_keys_recursively!(i)
|
||||
end
|
||||
object
|
||||
elsif object.respond_to?(:symbolize_keys!)
|
||||
object.symbolize_keys!
|
||||
else
|
||||
object
|
||||
when ::Hash
|
||||
_symbolize_keys!(object)
|
||||
end
|
||||
end
|
||||
|
||||
def _symbolize_keys!(hash)
|
||||
hash.keys.each do |k|
|
||||
_symbolize_keys_recursively!(hash[k])
|
||||
hash[k.to_sym] = hash.delete(k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,103 +1,12 @@
|
|||
require 'spec_helper'
|
||||
require 'support/module_context'
|
||||
|
||||
describe Hashie::Extensions::KeyConversion do
|
||||
subject do
|
||||
klass = Class.new(::Hash)
|
||||
klass.send :include, Hashie::Extensions::KeyConversion
|
||||
klass
|
||||
end
|
||||
include_context 'included hash module'
|
||||
|
||||
let(:instance) { subject.new }
|
||||
it { should respond_to(:stringify_keys) }
|
||||
it { should respond_to(:stringify_keys!) }
|
||||
|
||||
describe '#stringify_keys!' do
|
||||
it 'converts keys to strings' do
|
||||
instance[:abc] = 'abc'
|
||||
instance[123] = '123'
|
||||
instance.stringify_keys!
|
||||
expect((instance.keys & %w(abc 123)).size).to eq 2
|
||||
end
|
||||
|
||||
it 'performs deep conversion within nested hashes' do
|
||||
instance[:ab] = subject.new
|
||||
instance[:ab][:cd] = subject.new
|
||||
instance[:ab][:cd][:ef] = 'abcdef'
|
||||
instance.stringify_keys!
|
||||
expect(instance).to eq('ab' => { 'cd' => { 'ef' => 'abcdef' } })
|
||||
end
|
||||
|
||||
it 'performs deep conversion within nested arrays' do
|
||||
instance[:ab] = []
|
||||
instance[:ab] << subject.new
|
||||
instance[:ab] << subject.new
|
||||
instance[:ab][0][:cd] = 'abcd'
|
||||
instance[:ab][1][:ef] = 'abef'
|
||||
instance.stringify_keys!
|
||||
expect(instance).to eq('ab' => [{ 'cd' => 'abcd' }, { 'ef' => 'abef' }])
|
||||
end
|
||||
|
||||
it 'returns itself' do
|
||||
expect(instance.stringify_keys!).to eq instance
|
||||
end
|
||||
end
|
||||
|
||||
describe '#stringify_keys' do
|
||||
it 'converts keys to strings' do
|
||||
instance[:abc] = 'def'
|
||||
copy = instance.stringify_keys
|
||||
expect(copy['abc']).to eq 'def'
|
||||
end
|
||||
|
||||
it 'does not alter the original' do
|
||||
instance[:abc] = 'def'
|
||||
copy = instance.stringify_keys
|
||||
expect(instance.keys).to eq [:abc]
|
||||
expect(copy.keys).to eq %w(abc)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#symbolize_keys!' do
|
||||
it 'converts keys to symbols' do
|
||||
instance['abc'] = 'abc'
|
||||
instance['def'] = 'def'
|
||||
instance.symbolize_keys!
|
||||
expect((instance.keys & [:abc, :def]).size).to eq 2
|
||||
end
|
||||
|
||||
it 'performs deep conversion within nested hashes' do
|
||||
instance['ab'] = subject.new
|
||||
instance['ab']['cd'] = subject.new
|
||||
instance['ab']['cd']['ef'] = 'abcdef'
|
||||
instance.symbolize_keys!
|
||||
expect(instance).to eq(ab: { cd: { ef: 'abcdef' } })
|
||||
end
|
||||
|
||||
it 'performs deep conversion within nested arrays' do
|
||||
instance['ab'] = []
|
||||
instance['ab'] << subject.new
|
||||
instance['ab'] << subject.new
|
||||
instance['ab'][0]['cd'] = 'abcd'
|
||||
instance['ab'][1]['ef'] = 'abef'
|
||||
instance.symbolize_keys!
|
||||
expect(instance).to eq(ab: [{ cd: 'abcd' }, { ef: 'abef' }])
|
||||
end
|
||||
|
||||
it 'returns itself' do
|
||||
expect(instance.symbolize_keys!).to eq instance
|
||||
end
|
||||
end
|
||||
|
||||
describe '#symbolize_keys' do
|
||||
it 'converts keys to symbols' do
|
||||
instance['abc'] = 'def'
|
||||
copy = instance.symbolize_keys
|
||||
expect(copy[:abc]).to eq 'def'
|
||||
end
|
||||
|
||||
it 'does not alter the original' do
|
||||
instance['abc'] = 'def'
|
||||
copy = instance.symbolize_keys
|
||||
expect(instance.keys).to eq ['abc']
|
||||
expect(copy.keys).to eq [:abc]
|
||||
end
|
||||
end
|
||||
it { should respond_to(:symbolize_keys) }
|
||||
it { should respond_to(:symbolize_keys!) }
|
||||
end
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
require 'spec_helper'
|
||||
require 'support/module_context'
|
||||
|
||||
describe Hashie::Extensions::StringifyKeys do
|
||||
include_context 'included hash module'
|
||||
|
||||
describe '#stringify_keys!' do
|
||||
it 'converts keys to strings' do
|
||||
subject[:abc] = 'abc'
|
||||
subject[123] = '123'
|
||||
subject.stringify_keys!
|
||||
expect((subject.keys & %w(abc 123)).size).to eq 2
|
||||
end
|
||||
|
||||
it 'converts nested instances of the same class' do
|
||||
subject[:ab] = dummy_class.new
|
||||
subject[:ab][:cd] = dummy_class.new
|
||||
subject[:ab][:cd][:ef] = 'abcdef'
|
||||
subject.stringify_keys!
|
||||
expect(subject).to eq('ab' => { 'cd' => { 'ef' => 'abcdef' } })
|
||||
end
|
||||
|
||||
it 'converts nested hashes' do
|
||||
subject[:ab] = { cd: { ef: 'abcdef' } }
|
||||
subject.stringify_keys!
|
||||
expect(subject).to eq('ab' => { 'cd' => { 'ef' => 'abcdef' } })
|
||||
end
|
||||
|
||||
it 'converts nested arrays' do
|
||||
subject[:ab] = []
|
||||
subject[:ab] << dummy_class.new
|
||||
subject[:ab] << dummy_class.new
|
||||
subject[:ab][0][:cd] = 'abcd'
|
||||
subject[:ab][1][:ef] = 'abef'
|
||||
subject.stringify_keys!
|
||||
expect(subject).to eq('ab' => [{ 'cd' => 'abcd' }, { 'ef' => 'abef' }])
|
||||
end
|
||||
|
||||
it 'returns itself' do
|
||||
expect(subject.stringify_keys!).to eq subject
|
||||
end
|
||||
end
|
||||
|
||||
describe '#stringify_keys' do
|
||||
it 'converts keys to strings' do
|
||||
subject[:abc] = 'def'
|
||||
copy = subject.stringify_keys
|
||||
expect(copy['abc']).to eq 'def'
|
||||
end
|
||||
|
||||
it 'does not alter the original' do
|
||||
subject[:abc] = 'def'
|
||||
copy = subject.stringify_keys
|
||||
expect(subject.keys).to eq [:abc]
|
||||
expect(copy.keys).to eq %w(abc)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,58 @@
|
|||
require 'spec_helper'
|
||||
require 'support/module_context'
|
||||
|
||||
describe Hashie::Extensions::SymbolizeKeys do
|
||||
include_context 'included hash module'
|
||||
|
||||
describe '#symbolize_keys!' do
|
||||
it 'converts keys to symbols' do
|
||||
subject['abc'] = 'abc'
|
||||
subject['def'] = 'def'
|
||||
subject.symbolize_keys!
|
||||
expect((subject.keys & [:abc, :def]).size).to eq 2
|
||||
end
|
||||
|
||||
it 'converts nested instances of the same class' do
|
||||
subject['ab'] = dummy_class.new
|
||||
subject['ab']['cd'] = dummy_class.new
|
||||
subject['ab']['cd']['ef'] = 'abcdef'
|
||||
subject.symbolize_keys!
|
||||
expect(subject).to eq(ab: { cd: { ef: 'abcdef' } })
|
||||
end
|
||||
|
||||
it 'converts nested hashes' do
|
||||
subject['ab'] = { 'cd' => { 'ef' => 'abcdef' } }
|
||||
subject.symbolize_keys!
|
||||
expect(subject).to eq(ab: { cd: { ef: 'abcdef' } })
|
||||
end
|
||||
|
||||
it 'performs deep conversion within nested arrays' do
|
||||
subject['ab'] = []
|
||||
subject['ab'] << dummy_class.new
|
||||
subject['ab'] << dummy_class.new
|
||||
subject['ab'][0]['cd'] = 'abcd'
|
||||
subject['ab'][1]['ef'] = 'abef'
|
||||
subject.symbolize_keys!
|
||||
expect(subject).to eq(ab: [{ cd: 'abcd' }, { ef: 'abef' }])
|
||||
end
|
||||
|
||||
it 'returns itself' do
|
||||
expect(subject.symbolize_keys!).to eq subject
|
||||
end
|
||||
end
|
||||
|
||||
describe '#symbolize_keys' do
|
||||
it 'converts keys to symbols' do
|
||||
subject['abc'] = 'def'
|
||||
copy = subject.symbolize_keys
|
||||
expect(copy[:abc]).to eq 'def'
|
||||
end
|
||||
|
||||
it 'does not alter the original' do
|
||||
subject['abc'] = 'def'
|
||||
copy = subject.symbolize_keys
|
||||
expect(subject.keys).to eq ['abc']
|
||||
expect(copy.keys).to eq [:abc]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
shared_context 'included hash module' do
|
||||
let!(:dummy_class) do
|
||||
klass = Class.new(::Hash)
|
||||
klass.send :include, described_class
|
||||
klass
|
||||
end
|
||||
|
||||
subject do
|
||||
dummy_class.new
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue