diff options
author | gregory <greg2502@gmail.com> | 2014-06-19 07:28:40 -0400 |
---|---|---|
committer | dblock <dblock@dblock.org> | 2014-06-19 07:28:40 -0400 |
commit | 63724217f2717261441344b7d77dd9fcc1635f3a (patch) | |
tree | 9c3799cb8849843b508f2e65a24606763a01b7bd | |
parent | 17090acd6856b4feb48691d102dac410c41f1230 (diff) | |
download | hashie-63724217f2717261441344b7d77dd9fcc1635f3a.tar.gz |
Added Dash and Trash#update_attributes.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | lib/hashie/dash.rb | 17 | ||||
-rw-r--r-- | spec/hashie/dash_spec.rb | 51 |
4 files changed, 72 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b29de6..dbacf49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ **Note:** This version introduces several backward incompatible API changes. See [UPGRADING](UPGRADING.md) for details. +* [#172](https://github.com/intridea/hashie/pull/172): Added Dash and Trash#update_attributes - [@gregory](https://github.com/gregory). * [#169](https://github.com/intridea/hashie/pull/169): Hash#to_hash will also convert nested objects that implement to_hash - [@gregory](https://github.com/gregory). * [#150](https://github.com/intridea/hashie/pull/159): Handle nil intermediate object on deep fetch - [@stephenaument](https://github.com/stephenaument). * [#146](https://github.com/intridea/hashie/issues/146): Mash#respond_to? inconsistent with #method_missing and does not respond to #permitted? - [@dblock](https://github.com/dblock). @@ -205,6 +205,11 @@ p.occupation # => 'Rubyist' p.email # => 'abc@def.com' p[:awesome] # => NoMethodError p[:occupation] # => 'Rubyist' +p.update_attributes(name: 'Trudy', occupation: 'Evil') +p.occupation # => 'Evil' +p.name # => 'Trudy' +p.update_attributes(occupation: nil) +p.occupation # => 'Rubyist' ``` Properties defined as symbols are not the same thing as properties defined as strings. diff --git a/lib/hashie/dash.rb b/lib/hashie/dash.rb index 941e566..5a26861 100644 --- a/lib/hashie/dash.rb +++ b/lib/hashie/dash.rb @@ -91,7 +91,7 @@ module Hashie end initialize_attributes(attributes) - assert_required_properties_set! + assert_required_attributes_set! end alias_method :_regular_reader, :[] @@ -142,6 +142,19 @@ module Hashie self end + def update_attributes!(attributes) + initialize_attributes(attributes) + + self.class.defaults.each_pair do |prop, value| + self[prop] = begin + value.dup + rescue TypeError + value + end if self[prop].nil? + end + assert_required_attributes_set! + end + private def initialize_attributes(attributes) @@ -156,7 +169,7 @@ module Hashie end end - def assert_required_properties_set! + def assert_required_attributes_set! self.class.required_properties.each do |required_property| assert_property_set!(required_property) end diff --git a/spec/hashie/dash_spec.rb b/spec/hashie/dash_spec.rb index 04ce0aa..6b10a52 100644 --- a/spec/hashie/dash_spec.rb +++ b/spec/hashie/dash_spec.rb @@ -18,6 +18,14 @@ class DashNoRequiredTest < Hashie::Dash property :count, default: 0 end +class DashWithCoercion < Hashie::Dash + include Hashie::Extensions::Coercion + property :person + property :city + + coerce_key :person, ::DashNoRequiredTest +end + class PropertyBangTest < Hashie::Dash property :important! end @@ -266,6 +274,49 @@ describe DashTest do end end end + + describe '#update_attributes!(params)' do + let(:params) { { first_name: 'Alice', email: 'alice@example.com' } } + + context 'when there is coercion' do + let(:params_before) { { city: 'nyc', person: { first_name: 'Bob', email: 'bob@example.com' } } } + let(:params_after) { { city: 'sfo', person: { first_name: 'Alice', email: 'alice@example.com' } } } + + subject { DashWithCoercion.new(params_before) } + + it 'update the attributes' do + expect(subject.person.first_name).to eq params_before[:person][:first_name] + subject.update_attributes!(params_after) + expect(subject.person.first_name).to eq params_after[:person][:first_name] + end + end + + it 'update the attributes' do + subject.update_attributes!(params) + expect(subject.first_name).to eq params[:first_name] + expect(subject.email).to eq params[:email] + expect(subject.count).to eq subject.class.defaults[:count] + end + + context 'when required property is update to nil' do + let(:params) { { first_name: nil, email: 'alice@example.com' } } + + it 'raise an ArgumentError' do + expect { subject.update_attributes!(params) }.to raise_error(ArgumentError) + end + end + + context 'when a default property is update to nil' do + let(:params) { { count: nil, email: 'alice@example.com' } } + + it 'set the property back to the default value' do + subject.update_attributes!(params) + expect(subject.email).to eq params[:email] + expect(subject.count).to eq subject.class.defaults[:count] + end + end + end + end describe Hashie::Dash, 'inheritance' do |