diff options
author | Daniel Doubrovkine (dB.) @dblockdotorg <dblock@dblock.org> | 2015-10-27 11:28:43 -0700 |
---|---|---|
committer | Daniel Doubrovkine (dB.) @dblockdotorg <dblock@dblock.org> | 2015-10-27 11:28:43 -0700 |
commit | c71e4fd084635ccf37e3f2a63efd20b244147705 (patch) | |
tree | 18cdc8558e8b925abcdf08a57685274bf1336fef | |
parent | b65b849aec38805c88340dbb0b312460f3f4c2ce (diff) | |
parent | b2acb098aa8fa928b54815ace2c40922e24d1f64 (diff) | |
download | hashie-c71e4fd084635ccf37e3f2a63efd20b244147705.tar.gz |
Merge pull request #321 from luislavena/bk-240-clash-fixes
Clash: multiple bang notation calls
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | lib/hashie/clash.rb | 23 | ||||
-rw-r--r-- | spec/hashie/clash_spec.rb | 26 |
3 files changed, 37 insertions, 13 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 31a47ed..c2464b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * [#317](https://github.com/intridea/hashie/pull/317): Ensure `Hashie::Extensions::MethodQuery` methods return boolean values - [@michaelherold](https://github.com/michaelherold). * [#319](https://github.com/intridea/hashie/pull/319): Fix a regression from 3.4.1 where `Hashie::Extensions::DeepFind` is no longer indifference-aware - [@michaelherold](https://github.com/michaelherold). +* [#240](https://github.com/intridea/hashie/pull/240): Fixed nesting twice with Clash keys - [@bartoszkopinski](https://github.com/bartoszkopinski). * Your contribution here. ## 3.4.3 (10/25/2015) diff --git a/lib/hashie/clash.rb b/lib/hashie/clash.rb index 4bb755e..945c146 100644 --- a/lib/hashie/clash.rb +++ b/lib/hashie/clash.rb @@ -54,7 +54,7 @@ module Hashie case args.length when 1 val = args.first - val = self[key].merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash) + val = self.class.new(self[key]).merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash) else val = args end @@ -64,22 +64,23 @@ module Hashie end def method_missing(name, *args) #:nodoc: - name = name.to_s - if name.match(/!$/) && args.empty? + if args.empty? && name.to_s.end_with?('!') key = name[0...-1].to_sym - if self[key].nil? - self[key] = Clash.new({}, self) - elsif self[key].is_a?(::Hash) && !self[key].is_a?(Clash) - self[key] = Clash.new(self[key], self) + case self[key] + when NilClass + self[key] = self.class.new({}, self) + when Clash + self[key] + when Hash + self[key] = self.class.new(self[key], self) else fail ChainError, 'Tried to chain into a non-hash key.' end - - self[key] elsif args.any? - key = name.to_sym - merge_store(key, *args) + merge_store(name, *args) + else + super end end end diff --git a/spec/hashie/clash_spec.rb b/spec/hashie/clash_spec.rb index e30dd5c..6212a84 100644 --- a/spec/hashie/clash_spec.rb +++ b/spec/hashie/clash_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe Hashie::Clash do - subject { Hashie::Clash.new } - it 'is able to set an attribute via method_missing' do subject.foo('bar') expect(subject[:foo]).to eq 'bar' @@ -45,4 +43,28 @@ describe Hashie::Clash do expect(subject[:foo]).to be_nil expect(subject[:hello]).to be_nil end + + it 'merges multiple bang notation calls' do + subject.where!.foo(123) + subject.where!.bar(321) + expect(subject).to eq(where: { foo: 123, bar: 321 }) + end + + it 'raises an exception when method is missing' do + expect { subject.boo }.to raise_error(NoMethodError) + end + + describe 'when inherited' do + subject { Class.new(described_class).new } + + it 'bang nodes are instances of a subclass' do + subject.where!.foo(123) + expect(subject[:where]).to be_instance_of(subject.class) + end + + it 'merged nodes are instances of a subclass' do + subject.where(abc: 'def').where(hgi: 123) + expect(subject[:where]).to be_instance_of(subject.class) + end + end end |