diff options
author | Peter Brindisi <peter.brindisi@gmail.com> | 2014-04-06 08:42:16 -0400 |
---|---|---|
committer | dblock <dblock@dblock.org> | 2014-04-06 08:43:21 -0400 |
commit | c491e62ce4ef3605c5aecf8d7a51361a47ebddef (patch) | |
tree | c07e8ce338478b1f12b9c0d73b842926d7470ee6 | |
parent | e188a425073d34d385ed6241d63971e1dba883dd (diff) | |
download | hashie-c491e62ce4ef3605c5aecf8d7a51361a47ebddef.tar.gz |
IndifferentAccess now works without MergeInitializer.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | lib/hashie/extensions/indifferent_access.rb | 10 | ||||
-rw-r--r-- | spec/hashie/extensions/indifferent_access_spec.rb | 188 |
3 files changed, 127 insertions, 72 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index bcfb3a7..68ed47d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * [#113](https://github.com/intridea/hashie/issues/113): Fixed Hash#merge with Hashie::Dash - [@spencer1248](https://github.com/spencer1248). * [#99](https://github.com/intridea/hashie/issues/99): Hash#deep_merge raises errors when it encounters integers - [@defsprite](https://github.com/defsprite). * [#133](https://github.com/intridea/hashie/pull/133): Fixed Hash##to_hash with symbolize_keys - [@mhuggins](https://github.com/mhuggins). +* [#130](https://github.com/intridea/hashie/pull/130): IndifferentAccess now works without MergeInitializer - [@npj](https://github.com/npj). ## 2.0.5 diff --git a/lib/hashie/extensions/indifferent_access.rb b/lib/hashie/extensions/indifferent_access.rb index 5cecfae..8af278e 100644 --- a/lib/hashie/extensions/indifferent_access.rb +++ b/lib/hashie/extensions/indifferent_access.rb @@ -36,6 +36,16 @@ module Hashie %w(include? member? has_key?).each do |key_alias| alias_method key_alias, :indifferent_key? end + + class << self + def [](*) + super.convert! + end + + def try_convert(*) + (hash = super) && self[hash] + end + end end end diff --git a/spec/hashie/extensions/indifferent_access_spec.rb b/spec/hashie/extensions/indifferent_access_spec.rb index f1c7c0c..4dd6a03 100644 --- a/spec/hashie/extensions/indifferent_access_spec.rb +++ b/spec/hashie/extensions/indifferent_access_spec.rb @@ -1,108 +1,152 @@ require 'spec_helper' describe Hashie::Extensions::IndifferentAccess do - class IndifferentHash < Hash + + class IndifferentHashWithMergeInitializer < Hash include Hashie::Extensions::MergeInitializer include Hashie::Extensions::IndifferentAccess - end - subject { IndifferentHash } - - it 'should be able to access via string or symbol' do - h = subject.new(abc: 123) - h[:abc].should eq 123 - h['abc'].should eq 123 - end - describe '#store' do - it 'should indifferently save values' do - h = subject.new - h.store(:abc, 123) - h[:abc].should eq 123 - h['abc'].should eq 123 + class << self + alias_method :build, :new end end - describe '#values_at' do - it 'should indifferently find values' do - h = subject.new(:foo => 'bar', 'baz' => 'qux') - h.values_at('foo', :baz).should eq %w(bar qux) - end - end + class IndifferentHashWithArrayInitializer < Hash + include Hashie::Extensions::IndifferentAccess - describe '#fetch' do - it 'should work like normal fetch, but indifferent' do - h = subject.new(foo: 'bar') - h.fetch(:foo).should eq h.fetch('foo') - h.fetch(:foo).should eq 'bar' + class << self + alias_method :build, :[] end end - describe '#delete' do - it 'should delete indifferently' do - h = subject.new(:foo => 'bar', 'baz' => 'qux') - h.delete('foo') - h.delete(:baz) - h.should be_empty + class IndifferentHashWithTryConvertInitializer < Hash + include Hashie::Extensions::IndifferentAccess + + class << self + alias_method :build, :try_convert end end - describe '#key?' do - let(:h) { subject.new(foo: 'bar') } - - it 'should find it indifferently' do - h.should be_key(:foo) - h.should be_key('foo') + shared_examples_for 'hash with indifferent access' do + it 'should be able to access via string or symbol' do + h = subject.build(abc: 123) + h[:abc].should eq 123 + h['abc'].should eq 123 end - %w(include? member? has_key?).each do |key_alias| - it "should be aliased as #{key_alias}" do - h.send(key_alias.to_sym, :foo).should be(true) - h.send(key_alias.to_sym, 'foo').should be(true) + describe '#values_at' do + it 'should indifferently find values' do + h = subject.build(:foo => 'bar', 'baz' => 'qux') + h.values_at('foo', :baz).should eq %w(bar qux) end end - end - describe '#update' do - subject { IndifferentHash.new(foo: 'bar') } - it 'should allow keys to be indifferent still' do - subject.update(baz: 'qux') - subject['foo'].should eq 'bar' - subject['baz'].should eq 'qux' + describe '#fetch' do + it 'should work like normal fetch, but indifferent' do + h = subject.build(foo: 'bar') + h.fetch(:foo).should eq h.fetch('foo') + h.fetch(:foo).should eq 'bar' + end end - it 'should recursively inject indifference into sub-hashes' do - subject.update(baz: { qux: 'abc' }) - subject['baz']['qux'].should eq 'abc' + describe '#delete' do + it 'should delete indifferently' do + h = subject.build(:foo => 'bar', 'baz' => 'qux') + h.delete('foo') + h.delete(:baz) + h.should be_empty + end end - it 'should not change the ancestors of the injected object class' do - subject.update(baz: { qux: 'abc' }) - Hash.new.should_not be_respond_to(:indifferent_access?) - end - end + describe '#key?' do + let(:h) { subject.build(foo: 'bar') } - describe '#replace' do - subject do - IndifferentHash.new(foo: 'bar').replace(bar: 'baz', hi: 'bye') + it 'should find it indifferently' do + h.should be_key(:foo) + h.should be_key('foo') + end + + %w(include? member? has_key?).each do |key_alias| + it "should be aliased as #{key_alias}" do + h.send(key_alias.to_sym, :foo).should be(true) + h.send(key_alias.to_sym, 'foo').should be(true) + end + end end - it 'returns self' do - subject.should be_a(IndifferentHash) + describe '#update' do + let(:h) { subject.build(foo: 'bar') } + it 'should allow keys to be indifferent still' do + h.update(baz: 'qux') + h['foo'].should eq 'bar' + h['baz'].should eq 'qux' + end + + it 'should recursively inject indifference into sub-hashes' do + h.update(baz: { qux: 'abc' }) + h['baz']['qux'].should eq 'abc' + end + + it 'should not change the ancestors of the injected object class' do + h.update(baz: { qux: 'abc' }) + Hash.new.should_not be_respond_to(:indifferent_access?) + end end - it 'should remove old keys' do - [:foo, 'foo'].each do |k| - subject[k].should be_nil - subject.key?(k).should be_false + describe '#replace' do + let(:h) { subject.build(foo: 'bar').replace(bar: 'baz', hi: 'bye') } + + it 'returns self' do + h.should be_a(subject) + end + + it 'should remove old keys' do + [:foo, 'foo'].each do |k| + h[k].should be_nil + h.key?(k).should be_false + end + end + + it 'creates new keys with indifferent access' do + [:bar, 'bar', :hi, 'hi'].each { |k| h.key?(k).should be_true } + h[:bar].should eq 'baz' + h['bar'].should eq 'baz' + h[:hi].should eq 'bye' + h['hi'].should eq 'bye' end end - it 'creates new keys with indifferent access' do - [:bar, 'bar', :hi, 'hi'].each { |k| subject.key?(k).should be_true } - subject[:bar].should eq 'baz' - subject['bar'].should eq 'baz' - subject[:hi].should eq 'bye' - subject['hi'].should eq 'bye' + describe '::try_convert' do + describe 'with conversion' do + let(:h) { subject.try_convert(foo: 'bar') } + + it 'should be a subject' do + h.should be_a(subject) + end + end + + describe 'without conversion' do + let(:h) { subject.try_convert('{ :foo => bar }') } + + it 'should be nil' do + h.should be_nil + end + end end end + + describe 'with merge initializer' do + subject { IndifferentHashWithMergeInitializer } + it_should_behave_like 'hash with indifferent access' + end + + describe 'with array initializer' do + subject { IndifferentHashWithArrayInitializer } + it_should_behave_like 'hash with indifferent access' + end + + describe 'with try convert initializer' do + subject { IndifferentHashWithTryConvertInitializer } + it_should_behave_like 'hash with indifferent access' + end end |