From 40ed61792f8986410639f73bdf7aba950a675c8e Mon Sep 17 00:00:00 2001 From: Vladimir Sazhin Date: Mon, 10 Jun 2019 12:38:41 +0300 Subject: [PATCH 1/2] Fix #attribute_provided? behavior --- README.md | 17 +++++++++++++---- lib/tainbox/attribute_definer.rb | 4 ++-- spec/tainbox_spec.rb | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f2f508c..19298b4 100644 --- a/README.md +++ b/README.md @@ -64,18 +64,27 @@ end ### #attribute_provided? -Attribute is considered provided if its setter was explicitly invoked via a setter, `.new`, or `#attributes=` or it has a default value. +Attribute is considered provided if its setter was explicitly invoked via a setter, `.new`, or `#attributes=`. ``` ruby class Person include Tainbox - attribute :name, default: 'John' + attribute :name, default: 'Anonymous' attribute :age end -person = Person.new -person.attribute_provided?(:age) # => false +person = Person.new('age' => '24') + +person.attribute_provided?(:name) # => false +person.attribute_provided?(:age) # => true + +person.name = 'John' person.attribute_provided?(:name) # => true +person.attribute_provided?(:age) # => true + +person.attributes = {} +person.attribute_provided?(:name) # => false +person.attribute_provided?(:age) # => false ``` ### Disabling automatic attribute readers and writers diff --git a/lib/tainbox/attribute_definer.rb b/lib/tainbox/attribute_definer.rb index 0be57e5..fb1af12 100644 --- a/lib/tainbox/attribute_definer.rb +++ b/lib/tainbox/attribute_definer.rb @@ -41,14 +41,14 @@ def define_setter end define_method("tainbox_set_default_#{attribute}") do + tainbox_unregister_attribute_provided(attribute) + if args.has_key?(:default) - tainbox_register_attribute_provided(attribute) value = args[:default].deep_dup value = Tainbox::DeferredValue.new(value) if value.is_a?(Proc) instance_variable_set(:"@tainbox_#{attribute}", value) else - tainbox_unregister_attribute_provided(attribute) instance_variable_set(:"@tainbox_#{attribute}", nil) end end diff --git a/spec/tainbox_spec.rb b/spec/tainbox_spec.rb index df45762..215f982 100644 --- a/spec/tainbox_spec.rb +++ b/spec/tainbox_spec.rb @@ -23,7 +23,7 @@ def name person.attributes = {} expect(person.name).to eq('Oliver') expect(person.age).to be_nil - expect(person.attribute_provided?(:name)).to be_truthy + expect(person.attribute_provided?(:name)).to be_falsey expect(person.attribute_provided?(:age)).to be_falsey expect(person.attributes).to eq(name: 'Oliver', age: nil) From 6821ff6d7cf108a0e349aac4b79a599c160e9baf Mon Sep 17 00:00:00 2001 From: Vladimir Sazhin Date: Mon, 10 Jun 2019 13:22:27 +0300 Subject: [PATCH 2/2] New #provided_attributes method --- README.md | 5 ++++- lib/tainbox/instance_methods.rb | 4 ++++ spec/tainbox_spec.rb | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 19298b4..587a279 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ def name=(value) end ``` -### #attribute_provided? +### `#provided_attributes` and `#attribute_provided?` Attribute is considered provided if its setter was explicitly invoked via a setter, `.new`, or `#attributes=`. @@ -75,14 +75,17 @@ end person = Person.new('age' => '24') +person.provided_attributes # => [:age] person.attribute_provided?(:name) # => false person.attribute_provided?(:age) # => true person.name = 'John' +person.provided_attributes # => [:name, :age] person.attribute_provided?(:name) # => true person.attribute_provided?(:age) # => true person.attributes = {} +person.provided_attributes # => [] person.attribute_provided?(:name) # => false person.attribute_provided?(:age) # => false ``` diff --git a/lib/tainbox/instance_methods.rb b/lib/tainbox/instance_methods.rb index ab86ac1..e93adf7 100644 --- a/lib/tainbox/instance_methods.rb +++ b/lib/tainbox/instance_methods.rb @@ -41,6 +41,10 @@ def attributes=(attributes) end end + def provided_attributes + self.class.tainbox_attributes & tainbox_provided_attributes + end + def attribute_provided?(attribute) tainbox_provided_attributes.include?(attribute.to_sym) end diff --git a/spec/tainbox_spec.rb b/spec/tainbox_spec.rb index 215f982..3896346 100644 --- a/spec/tainbox_spec.rb +++ b/spec/tainbox_spec.rb @@ -19,6 +19,7 @@ def name expect(person.age).to eq(24) expect(person.attribute_provided?(:name)).to be_truthy expect(person.attribute_provided?(:age)).to be_truthy + expect(person.provided_attributes).to eq(%i[name age]) person.attributes = {} expect(person.name).to eq('Oliver') @@ -27,11 +28,14 @@ def name expect(person.attribute_provided?(:age)).to be_falsey expect(person.attributes).to eq(name: 'Oliver', age: nil) + expect(person.provided_attributes).to be_empty person.age = 10 expect(person.age).to eq(10) expect(person.attribute_provided?(:age)).to be_truthy + expect(person.provided_attributes).to eq(%i[age]) + expect(person.as_json).to eq('name' => 'Oliver', 'age' => 10) expect(person.as_json(only: :name)).to eq('name' => 'Oliver') expect(person.as_json(except: :name)).to eq('age' => 10)