diff --git a/Gemfile.lock b/Gemfile.lock index ed568f4e..bd2fd904 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,6 +36,7 @@ GEM byebug (11.1.3) childprocess (4.1.0) climate_control (1.2.0) + coderay (1.1.3) colorize (1.1.0) concurrent-ruby (1.2.2) coveralls_reborn (0.27.0) @@ -115,6 +116,7 @@ GEM i18n (1.14.1) concurrent-ruby (~> 1.0) iniparse (1.5.0) + method_source (1.1.0) mini_portile2 (2.8.2) minitest (5.18.1) multipart-post (2.3.0) @@ -133,6 +135,9 @@ GEM racc pd_ruby (0.2.3) colorize + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) public_suffix (5.0.1) racc (1.7.1) rack (3.0.8) @@ -205,6 +210,7 @@ DEPENDENCIES factory_bot (~> 6.1.0) ledger_sync! overcommit (~> 0.57.0) + pry rake (~> 13.0) rspec (~> 3.2) rubocop (= 1.0.0) diff --git a/ledger_sync.gemspec b/ledger_sync.gemspec index 959dce96..2b17a5bc 100644 --- a/ledger_sync.gemspec +++ b/ledger_sync.gemspec @@ -38,6 +38,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency('coveralls_reborn') spec.add_development_dependency('factory_bot', '~> 6.1.0') spec.add_development_dependency('overcommit', '~> 0.57.0') + spec.add_development_dependency('pry') spec.add_development_dependency('rake', '~> 13.0') spec.add_development_dependency('rspec', '~> 3.2') spec.add_development_dependency('rubocop', '1.0.0') diff --git a/lib/ledger_sync.rb b/lib/ledger_sync.rb index 142eff8f..d630c61b 100644 --- a/lib/ledger_sync.rb +++ b/lib/ledger_sync.rb @@ -15,6 +15,7 @@ require 'faraday' require 'tempfile' require 'pd_ruby' +require 'pry' # Version require 'ledger_sync/version' diff --git a/lib/ledger_sync/resource_attribute.rb b/lib/ledger_sync/resource_attribute.rb index f9a75ce9..8e01b2e9 100644 --- a/lib/ledger_sync/resource_attribute.rb +++ b/lib/ledger_sync/resource_attribute.rb @@ -37,16 +37,16 @@ def assert_valid(args = {}) value = args.fetch(:value) type.assert_valid(value: value) - rescue Error::TypeError::ValueClassError - raise ResourceAttributeError::TypeError.new( - attribute: self, - resource_class: resource_class, - value: value - ) + # rescue Error::TypeError::ValueClassError + # raise ResourceAttributeError::TypeError.new( + # attribute: self, + # resource_class: resource_class, + # value: value + # ) end def cast(value) - type.cast(value: value) + cast_val(value) end # This is for ActiveModel::Dirty, since we define @attributes @@ -65,12 +65,16 @@ def valid_with?(value:) end def value=(val) - @value = type.cast(value: val) + @value = cast_val(val) end def will_change?(val) assert_valid(value: val) - value != type.cast(value: val) + value != cast_val(val) + end + + def cast_val(val) + type.cast(value: val) end end end diff --git a/lib/ledger_sync/serialization/attribute.rb b/lib/ledger_sync/serialization/attribute.rb index 6140770b..dc6a962e 100644 --- a/lib/ledger_sync/serialization/attribute.rb +++ b/lib/ledger_sync/serialization/attribute.rb @@ -6,6 +6,7 @@ module LedgerSync module Serialization class Attribute attr_reader :block, + :default, :hash_attribute, :if_method, :resource_attribute, @@ -14,6 +15,7 @@ class Attribute def initialize(args = {}) @block = args.fetch(:block, nil) + @default = args.fetch(:default, nil) @hash_attribute = args.fetch(:hash_attribute, nil).try(:to_s) @resource_attribute = args.fetch(:resource_attribute, nil).try(:to_s) @resource_class = args.fetch(:resource_class, nil) diff --git a/lib/ledger_sync/serialization/deserializer_attribute.rb b/lib/ledger_sync/serialization/deserializer_attribute.rb index 789c1e89..d8e174eb 100644 --- a/lib/ledger_sync/serialization/deserializer_attribute.rb +++ b/lib/ledger_sync/serialization/deserializer_attribute.rb @@ -31,9 +31,9 @@ def value_from_hash(hash:, resource:) value = hash.dig(*hash_attribute.split('.')) if type.is_a?(Type::DeserializerType) - type.cast(deserializer_attribute: self, resource: resource, value: value) + type.cast(deserializer_attribute: self, resource: resource, value: value, default: default) else - value = type.cast(value: value) + value = type.cast(value: value, default: default) return value if resource_attribute_dot_parts.count <= 1 nested_resource = resource.send(resource_attribute_dot_parts.first) diff --git a/lib/ledger_sync/serialization/mixin.rb b/lib/ledger_sync/serialization/mixin.rb index d7fc546c..6217be97 100644 --- a/lib/ledger_sync/serialization/mixin.rb +++ b/lib/ledger_sync/serialization/mixin.rb @@ -47,6 +47,7 @@ def _build_attribute(args) serializer = args.fetch(:serializer, nil) type = args.fetch(:type, nil) if_method = args.fetch(:if, nil) + default = args.fetch(:default, nil) attribute_class.new( block: block, @@ -55,7 +56,8 @@ def _build_attribute(args) resource_attribute: resource_attribute, resource_class: resource_class, serializer: serializer, - type: type + type: type, + default: default ) end end diff --git a/lib/ledger_sync/serialization/type/deserializer_references_many_type.rb b/lib/ledger_sync/serialization/type/deserializer_references_many_type.rb index 828d0f5a..15099d69 100644 --- a/lib/ledger_sync/serialization/type/deserializer_references_many_type.rb +++ b/lib/ledger_sync/serialization/type/deserializer_references_many_type.rb @@ -10,8 +10,9 @@ def cast_value(args = {}) deserializer_attribute = args.fetch(:deserializer_attribute) value = args.fetch(:value) resource = args.fetch(:resource) + default = args.fetch(:default, nil) - return if value.nil? + return default if value.nil? first_dot = deserializer_attribute.resource_attribute_dot_parts.first.to_sym nested_resource = resource.class.resource_attributes[first_dot].type.resource_class.new diff --git a/lib/ledger_sync/serialization/type/deserializer_type.rb b/lib/ledger_sync/serialization/type/deserializer_type.rb index 8e298b70..7bbbfff1 100644 --- a/lib/ledger_sync/serialization/type/deserializer_type.rb +++ b/lib/ledger_sync/serialization/type/deserializer_type.rb @@ -16,12 +16,14 @@ def cast_value(args = {}) deserializer_attribute = args.fetch(:deserializer_attribute) resource = args.fetch(:resource) value = args.fetch(:value) + default = args.fetch(:default, nil) + + return default if value.nil? first_dot = deserializer_attribute.resource_attribute_dot_parts.first.to_sym nested_resource = resource.send(first_dot) nested_resource ||= resource.class.resource_attributes[first_dot].type.resource_class.new - return if value.nil? deserializer.new.deserialize(hash: value, resource: nested_resource) end diff --git a/lib/ledger_sync/type/reference_many.rb b/lib/ledger_sync/type/reference_many.rb index 626f66a6..30a725c6 100644 --- a/lib/ledger_sync/type/reference_many.rb +++ b/lib/ledger_sync/type/reference_many.rb @@ -16,7 +16,10 @@ def initialize(resource_class:) def cast(args = {}) value = args.fetch(:value) - return if value.nil? + default = args.fetch(:default, nil) + + pd default + return default if value.nil? many_array_class = LedgerSync::ResourceAttribute::Reference::Many::ManyArray @@ -33,7 +36,9 @@ def type end def valid?(args = {}) - value = args.fetch(:value) + pd args + value = args.fetch(:value, args.fetch(:default, nil)) + return false unless value.is_a?(Array) return true if (resource_classes & value.map(&:class)).any? return true if value.is_a?(Array) && value.empty? diff --git a/lib/ledger_sync/type/value_mixin.rb b/lib/ledger_sync/type/value_mixin.rb index 937108b4..793c6728 100644 --- a/lib/ledger_sync/type/value_mixin.rb +++ b/lib/ledger_sync/type/value_mixin.rb @@ -9,6 +9,8 @@ def self.included(base) end def assert_valid(args = {}) + pd self + pd valid?(args) return if valid?(args) value = args.fetch(:value) @@ -22,7 +24,8 @@ def assert_valid(args = {}) # Do not override this method. Override private method cast_value def cast(args = {}) assert_valid(args) - return nil if args.fetch(:value).nil? + + return args.fetch(:default, nil) if args.fetch(:value).nil? cast_value(args) end @@ -41,10 +44,16 @@ def cast_value(args = {}) end def valid_class?(args = {}) - value = args.fetch(:value) + # value = args.fetch(:value) + value = args.fetch(:value, args.fetch(:default, nil)) + pd args + pd value + pd value.nil? return true if value.nil? + pd return true if valid_classes.select { |e| value.is_a?(e) }.any? + pd false end diff --git a/spec/deserializer_spec.rb b/spec/deserializer_spec.rb index 6cf219b0..330c938e 100644 --- a/spec/deserializer_spec.rb +++ b/spec/deserializer_spec.rb @@ -11,6 +11,26 @@ end end + let(:references_many_deserializer_class) do + Class.new(LedgerSync::Deserializer) do + references_many :objs, deserializer: LedgerSync::Ledgers::TestLedger::Subsidiary::Deserializer + end + end + + let(:references_many_deserializer) do + references_many_deserializer_class.new + end + + let(:references_many_with_default_deserializer_class) do + Class.new(LedgerSync::Deserializer) do + references_many :objs, deserializer: LedgerSync::Ledgers::TestLedger::Subsidiary::Deserializer, default: [] + end + end + + let(:references_many_with_default_deserializer) do + references_many_with_default_deserializer_class.new + end + let(:custom_deserializer_class) do Class.new(LedgerSync::Deserializer) do attribute :foo, @@ -38,10 +58,40 @@ name phone_number type - ] + ], + references_many: [ + [:objs] + ], + reference_class: LedgerSync::Ledgers::TestLedger::Subsidiary ) end + # let(:custom_references_nany_resource_class) do + # Object.const_set( + # test_resource_class_name, + # Class.new(LedgerSync::Resource) do + # references_many :objs, to: LedgerSync::Ledgers::TestLedger::Subsidiary::Deserializer + # end + # ) + # end + + # let(:test_references_many_resource) do + # custom_references_nany_resource_class.new + # end + + # let(:custom_references_nany_with_default_resource_class) do + # Object.const_set( + # test_resource_class_name, + # Class.new(LedgerSync::Resource) do + # references_many :objs, to: LedgerSync::Ledgers::TestLedger::Subsidiary::Deserializer, default: [] + # end + # ) + # end + + # let(:test_references_many_with_default_resource) do + # custom_references_nany_resource_class.new + # end + it { expect(described_class).to respond_to(:attribute) } it { expect(described_class).to respond_to(:references_many) } it { expect(described_class).to respond_to(:references_one) } @@ -142,5 +192,18 @@ expect(dresource.foo).to eq('asdf') end end + + context 'with references_many' do + it do + dresource = references_many_deserializer.deserialize(hash: {}, resource: test_resource) + expect(dresource.objs).to eq(nil) + end + + it do + # binding.pry + dresource = references_many_with_default_deserializer.deserialize(hash: {}, resource: test_resource) + expect(dresource.objs).to eq([]) + end + end end end diff --git a/spec/support/resource_helpers.rb b/spec/support/resource_helpers.rb index b4a58c15..4b47bfc6 100644 --- a/spec/support/resource_helpers.rb +++ b/spec/support/resource_helpers.rb @@ -1,8 +1,12 @@ # frozen_string_literal: true module ResourceHelpers + def test_resource_class_name + "#{test_run_id}TestCustomResource#{test_resource_counter_increment!}" + end + def new_resource_class(args = {}) # rubocop:disable Metrics/CyclomaticComplexity - class_name = args.fetch(:name, "#{test_run_id}TestCustomResource#{test_resource_counter_increment!}") + class_name = args.fetch(:name, test_resource_class_name) remove_customer_resource_class(class_name: class_name) @@ -31,9 +35,9 @@ def new_resource_class(args = {}) # rubocop:disable Metrics/CyclomaticComplexity references_one a[0], **{ to: reference_class }.merge(a[1] || {}) end - references_many = args.fetch(:references_many, []) - references_many = Array(references_many) - references_many.each do |a| + references_manies = args.fetch(:references_many, []) + references_manies = Array(references_manies) + references_manies.each do |a| a = Array(a) references_many a[0], **{ to: reference_class }.merge(a[1] || {}) end