diff --git a/CHANGELOG.md b/CHANGELOG.md index 2271c87..6623ce2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## [Unreleased] +## [0.1.1] - 2023-02-22 + +- Add support for inheritance + ## [0.1.0] - 2023-02-21 - Initial release diff --git a/lib/shale/builder.rb b/lib/shale/builder.rb index ec48435..fa929eb 100644 --- a/lib/shale/builder.rb +++ b/lib/shale/builder.rb @@ -38,11 +38,21 @@ module Shale # module Builder class << self - # Gets called after including this module. + # Gets called after including this module in a module or class. # - # @param mod [Module] + # @param mod [Module, Class] + # @return [void] def included(mod) mod.extend ClassMethods + Builder.prepare_mod(mod) + end + + # Prepares the received module or class + # for dynamic method definition. + # + # @param mod [Module, Class] + # @return [void] + def prepare_mod(mod) builder_methods_module = ::Module.new mod.instance_variable_set :@builder_methods_module, builder_methods_module mod.include builder_methods_module @@ -51,6 +61,13 @@ def included(mod) # Class methods provided by `Shale::Builder` module ClassMethods + # @param subclass [Class] + # @return [void] + def inherited(subclass) + super + Builder.prepare_mod(subclass) + end + # Contains overridden getter methods for attributes # with complex types (so that they accept a block for building) # diff --git a/shale-builder.gemspec b/shale-builder.gemspec index 1a22367..e7c96b7 100644 --- a/shale-builder.gemspec +++ b/shale-builder.gemspec @@ -16,6 +16,7 @@ Gem::Specification.new do |spec| spec.metadata['homepage_uri'] = spec.homepage spec.metadata['source_code_uri'] = spec.homepage + spec.metadata['changelog_uri'] = 'https://github.com/Verseth/ruby-shale-builder/blob/main/CHANGELOG.md' # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. diff --git a/test/shale/builder_test.rb b/test/shale/builder_test.rb index ec45e31..3002f9f 100644 --- a/test/shale/builder_test.rb +++ b/test/shale/builder_test.rb @@ -29,8 +29,61 @@ class TestTransactionType < ::Shale::Mapper attribute :amount, TestAmountType end + class TestClientDataType < ::Shale::Mapper + include ::Shale::Builder + + attribute :first_name, ::Shale::Type::String + attribute :last_name, ::Shale::Type::String + attribute :email, ::Shale::Type::String + end + + class TestEnhancedTransactionType < TestTransactionType + attribute :client_data, TestClientDataType + end + + context 'inheritance' do + should 'correctly set up a class after inheriting' do + mod_parent = TestTransactionType.builder_methods_module + mod_child = TestEnhancedTransactionType.builder_methods_module + assert mod_parent.is_a?(::Module) + assert mod_child.is_a?(::Module) + assert !mod_child.equal?(mod_parent) + assert TestTransactionType.include?(mod_parent) + assert !TestTransactionType.include?(mod_child) + assert TestEnhancedTransactionType.include?(mod_child) + assert TestEnhancedTransactionType.include?(mod_parent) + assert_equal %i[amount], mod_parent.instance_methods + assert_equal %i[client_data], mod_child.instance_methods + end + + should 'correctly build an instance of a subclass' do + obj = TestEnhancedTransactionType.build do |t| + t.cvv_code = '321' + t.amount do |a| + a.value = 45.0 + a.currency = 'USD' + end + t.client_data do |c| + c.first_name = 'Dupa' + c.last_name = 'Kret' + c.email = 'something@example.com' + end + end + + assert obj.is_a?(TestEnhancedTransactionType) + assert_equal '321', obj.cvv_code + assert obj.amount.is_a?(TestAmountType) + assert_equal 45.0, obj.amount.value + assert_equal 'USD', obj.amount.currency + assert obj.client_data.is_a?(TestClientDataType) + assert_equal 'Dupa', obj.client_data.first_name + assert_equal 'Kret', obj.client_data.last_name + assert_equal 'something@example.com', obj.client_data.email + end + end + - should 'correctly set up a class after inheriting' do + should 'correctly set up a class after including' do mod = TestTransactionType.builder_methods_module assert mod.is_a?(::Module) assert TestTransactionType.include?(mod)