From 3e3f4b79f0ca441d682beda0775e32365c42bf6e Mon Sep 17 00:00:00 2001 From: loadkpi Date: Mon, 16 Apr 2018 18:10:28 +0300 Subject: [PATCH] default option fix --- lib/tainbox/attribute_definer.rb | 7 +++--- lib/tainbox/class_methods.rb | 4 ++-- lib/tainbox/instance_methods.rb | 2 +- spec/tainbox_spec.rb | 41 ++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/lib/tainbox/attribute_definer.rb b/lib/tainbox/attribute_definer.rb index 0be57e5..33bbb43 100644 --- a/lib/tainbox/attribute_definer.rb +++ b/lib/tainbox/attribute_definer.rb @@ -13,7 +13,7 @@ def initialize(klass, attribute_name, requested_type, requested_args) @requested_args = requested_args end - def define_getter + def define_getter(public_access = true) klass.tainbox_register_attribute(attribute_name) attribute = attribute_name @@ -22,10 +22,11 @@ def define_getter value = instance_variable_get(:"@tainbox_#{attribute}") value.is_a?(Tainbox::DeferredValue) ? instance_exec(&value.proc) : value end + send(:private, attribute) unless public_access end end - def define_setter + def define_setter(public_access = true) klass.tainbox_register_attribute(attribute_name) attribute = attribute_name @@ -33,12 +34,12 @@ def define_setter type = requested_type klass.tainbox_layer.instance_eval do - define_method("#{attribute}=") do |value| tainbox_register_attribute_provided(attribute) value = Tainbox::TypeConverter.new(type, value, options: args).convert if type instance_variable_set(:"@tainbox_#{attribute}", value) end + send(:private, "#{attribute}=") unless public_access define_method("tainbox_set_default_#{attribute}") do if args.has_key?(:default) diff --git a/lib/tainbox/class_methods.rb b/lib/tainbox/class_methods.rb index 41dc00a..4732597 100644 --- a/lib/tainbox/class_methods.rb +++ b/lib/tainbox/class_methods.rb @@ -26,8 +26,8 @@ def attribute(name, type = nil, **args) define_writer = args.fetch(:writer, true) definer = Tainbox::AttributeDefiner.new(self, name, type, args) - definer.define_getter if define_reader - definer.define_setter if define_writer + definer.define_getter(define_reader) + definer.define_setter(define_writer) end def suppress_tainbox_initializer! diff --git a/lib/tainbox/instance_methods.rb b/lib/tainbox/instance_methods.rb index ab86ac1..b8de4f2 100644 --- a/lib/tainbox/instance_methods.rb +++ b/lib/tainbox/instance_methods.rb @@ -16,7 +16,7 @@ def initialize(*args) def attributes self.class.tainbox_attributes.map do |attribute| - [attribute, send(attribute)] if respond_to?(attribute, true) + [attribute, send(attribute)] if respond_to?(attribute) end.compact.to_h end diff --git a/spec/tainbox_spec.rb b/spec/tainbox_spec.rb index df45762..599e303 100644 --- a/spec/tainbox_spec.rb +++ b/spec/tainbox_spec.rb @@ -57,6 +57,47 @@ def name expect { person.new('Hello world') }.to raise_exception(ArgumentError, exception) end + describe 'defining getter' do + let(:person) do + Class.new do + include Tainbox + attribute :name, default: 'Julyan', writer: false + end.new + end + + it 'read the default value' do + expect(person.name).to eq('Julyan') + end + + it 'does not allow to change the attribute value' do + expect { person.name = 'Adele' }.to raise_exception(NoMethodError) + end + end + + describe 'defining setter' do + let(:person) do + Class.new do + include Tainbox + attribute :name, default: 'Julyan', reader: false + end.new + end + + it 'has the default value' do + expect(person.send(:name)).to eq('Julyan') + end + + it 'allows to change the attribute value' do + person.name = 'Adele' + expect(person.send(:name)).to eq('Adele') + end + + describe '#attributes' do + it "doesn't contain defined attribute" do + expect(person.attributes).not_to have_key(:name) + end + end + end + describe 'string converter options' do describe 'no options' do