summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Herold <michael.j.herold+github@gmail.com>2015-06-10 18:40:10 -0400
committerMichael Herold <michael.j.herold+github@gmail.com>2015-06-10 18:40:10 -0400
commitedeef5633c9b5efb288bc5ad4530b286470a9196 (patch)
tree56a2667e2deef61ba389c9a1a8b219fe44bb65ee
parentb7405dca6d8d03c1650083119215a6eaf4125d91 (diff)
parent489309af7ffd8b4fe02bd839924b319cba8aa318 (diff)
downloadhashie-edeef5633c9b5efb288bc5ad4530b286470a9196.tar.gz
Merge pull request #304 from regexident/master
Fixed #303 (deep_merge/stringify_keys/symbolize_keys not working via hash.extend(…))
-rw-r--r--CHANGELOG.md1
-rw-r--r--lib/hashie/extensions/deep_merge.rb4
-rw-r--r--lib/hashie/extensions/stringify_keys.rb11
-rw-r--r--lib/hashie/extensions/symbolize_keys.rb13
-rw-r--r--spec/hashie/extensions/deep_merge_spec.rb20
-rw-r--r--spec/hashie/extensions/stringify_keys_spec.rb23
-rw-r--r--spec/hashie/extensions/symbolize_keys_spec.rb23
7 files changed, 85 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a5740cf..81d2289 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
## Next Release
* Your contribution here.
+* [#304](https://github.com/intridea/hashie/pull/304): Ensured compatibility of `Hash` extensions with singleton objects - [@regexident](https://github.com/regexident).
## 3.4.2 (6/2/2015)
diff --git a/lib/hashie/extensions/deep_merge.rb b/lib/hashie/extensions/deep_merge.rb
index d7222a3..df0887d 100644
--- a/lib/hashie/extensions/deep_merge.rb
+++ b/lib/hashie/extensions/deep_merge.rb
@@ -3,7 +3,9 @@ module Hashie
module DeepMerge
# Returns a new hash with +self+ and +other_hash+ merged recursively.
def deep_merge(other_hash, &block)
- dup.deep_merge!(other_hash, &block)
+ copy = dup
+ copy.extend(Hashie::Extensions::DeepMerge) unless copy.respond_to?(:deep_merge!)
+ copy.deep_merge!(other_hash, &block)
end
# Returns a new hash with +self+ and +other_hash+ merged recursively.
diff --git a/lib/hashie/extensions/stringify_keys.rb b/lib/hashie/extensions/stringify_keys.rb
index 13d50bc..41b0fe3 100644
--- a/lib/hashie/extensions/stringify_keys.rb
+++ b/lib/hashie/extensions/stringify_keys.rb
@@ -15,7 +15,7 @@ module Hashie
# Return a new hash with all keys converted
# to strings.
def stringify_keys
- dup.stringify_keys!
+ StringifyKeys.stringify_keys(self)
end
module ClassMethods
@@ -25,7 +25,7 @@ module Hashie
def stringify_keys_recursively!(object)
case object
when self.class
- object.stringify_keys!
+ stringify_keys!(object)
when ::Array
object.each do |i|
stringify_keys_recursively!(i)
@@ -43,6 +43,7 @@ module Hashie
# test.stringify_keys!
# test # => {'abc' => 'def'}
def stringify_keys!(hash)
+ hash.extend(Hashie::Extensions::StringifyKeys) unless hash.respond_to?(:stringify_keys!)
hash.keys.each do |k|
stringify_keys_recursively!(hash[k])
hash[k.to_s] = hash.delete(k)
@@ -54,8 +55,10 @@ module Hashie
# to strings.
# @param [::Hash] hash
def stringify_keys(hash)
- hash.dup.tap do | new_hash |
- stringify_keys! new_hash
+ copy = hash.dup
+ copy.extend(Hashie::Extensions::StringifyKeys) unless copy.respond_to?(:stringify_keys!)
+ copy.tap do |new_hash|
+ stringify_keys!(new_hash)
end
end
end
diff --git a/lib/hashie/extensions/symbolize_keys.rb b/lib/hashie/extensions/symbolize_keys.rb
index 12d0669..274889c 100644
--- a/lib/hashie/extensions/symbolize_keys.rb
+++ b/lib/hashie/extensions/symbolize_keys.rb
@@ -15,7 +15,7 @@ module Hashie
# Return a new hash with all keys converted
# to symbols.
def symbolize_keys
- dup.symbolize_keys!
+ SymbolizeKeys.symbolize_keys(self)
end
module ClassMethods
@@ -23,9 +23,9 @@ module Hashie
# hashes and arrays.
# @api private
def symbolize_keys_recursively!(object)
- object.symbolize_keys! if object.respond_to? :symbolize_keys!
-
case object
+ when self.class
+ symbolize_keys!(object)
when ::Array
object.each do |i|
symbolize_keys_recursively!(i)
@@ -43,6 +43,7 @@ module Hashie
# Hashie.symbolize_keys! test
# test # => {:abc => 'def'}
def symbolize_keys!(hash)
+ hash.extend(Hashie::Extensions::SymbolizeKeys) unless hash.respond_to?(:symbolize_keys!)
hash.keys.each do |k|
symbolize_keys_recursively!(hash[k])
hash[k.to_sym] = hash.delete(k)
@@ -54,8 +55,10 @@ module Hashie
# to symbols.
# @param [::Hash] hash
def symbolize_keys(hash)
- hash.dup.tap do | new_hash |
- symbolize_keys! new_hash
+ copy = hash.dup
+ copy.extend(Hashie::Extensions::SymbolizeKeys) unless copy.respond_to?(:symbolize_keys!)
+ copy.tap do |new_hash|
+ symbolize_keys!(new_hash)
end
end
end
diff --git a/spec/hashie/extensions/deep_merge_spec.rb b/spec/hashie/extensions/deep_merge_spec.rb
index cd68523..0815c15 100644
--- a/spec/hashie/extensions/deep_merge_spec.rb
+++ b/spec/hashie/extensions/deep_merge_spec.rb
@@ -42,4 +42,24 @@ describe Hashie::Extensions::DeepMerge do
expect(h1).to eq expected_hash
end
end
+
+ context 'from extended object' do
+ subject { Hash }
+ let(:h1) { subject.new.merge(a: 100, c: { c1: 100 }).extend(Hashie::Extensions::DeepMerge) }
+ let(:h2) { { b: 250, c: { c1: 200 } } }
+ let(:expected_hash) { { a: 100, b: 250, c: { c1: 200 } } }
+
+ it 'does not raise error' do
+ expect { h1.deep_merge(h2) } .not_to raise_error
+ end
+
+ it 'deep merges two hashes' do
+ expect(h1.deep_merge(h2)).to eq expected_hash
+ end
+
+ it 'deep merges another hash in place via bang method' do
+ h1.deep_merge!(h2)
+ expect(h1).to eq expected_hash
+ end
+ end
end
diff --git a/spec/hashie/extensions/stringify_keys_spec.rb b/spec/hashie/extensions/stringify_keys_spec.rb
index b0f8aa6..f5f78d8 100644
--- a/spec/hashie/extensions/stringify_keys_spec.rb
+++ b/spec/hashie/extensions/stringify_keys_spec.rb
@@ -80,6 +80,29 @@ describe Hashie::Extensions::StringifyKeys do
include_examples 'stringify_keys!'
end
end
+
+ context 'singleton methods' do
+ subject { Hash }
+ let(:object) { subject.new.merge(a: 1, b: { c: 2 }).extend(Hashie::Extensions::StringifyKeys) }
+ let(:expected_hash) { { 'a' => 1, 'b' => { 'c' => 2 } } }
+
+ describe '.stringify_keys' do
+ it 'does not raise error' do
+ expect { object.stringify_keys } .not_to raise_error
+ end
+ it 'produces expected stringified hash' do
+ expect(object.stringify_keys).to eq(expected_hash)
+ end
+ end
+ describe '.stringify_keys!' do
+ it 'does not raise error' do
+ expect { object.stringify_keys! } .not_to raise_error
+ end
+ it 'produces expected stringified hash' do
+ expect(object.stringify_keys!).to eq(expected_hash)
+ end
+ end
+ end
end
describe Hashie do
diff --git a/spec/hashie/extensions/symbolize_keys_spec.rb b/spec/hashie/extensions/symbolize_keys_spec.rb
index 862117b..b62fbe4 100644
--- a/spec/hashie/extensions/symbolize_keys_spec.rb
+++ b/spec/hashie/extensions/symbolize_keys_spec.rb
@@ -85,6 +85,29 @@ describe Hashie::Extensions::SymbolizeKeys do
include_examples 'symbolize_keys!'
end
end
+
+ context 'singleton methods' do
+ subject { Hash }
+ let(:object) { subject.new.merge('a' => 1, 'b' => { 'c' => 2 }).extend(Hashie::Extensions::SymbolizeKeys) }
+ let(:expected_hash) { { a: 1, b: { c: 2 } } }
+
+ describe '.symbolize_keys' do
+ it 'does not raise error' do
+ expect { object.symbolize_keys }.not_to raise_error
+ end
+ it 'produces expected symbolized hash' do
+ expect(object.symbolize_keys).to eq(expected_hash)
+ end
+ end
+ describe '.symbolize_keys!' do
+ it 'does not raise error' do
+ expect { object.symbolize_keys! }.not_to raise_error
+ end
+ it 'produces expected symbolized hash' do
+ expect(object.symbolize_keys!).to eq(expected_hash)
+ end
+ end
+ end
end
describe Hashie do