Skip to content

Commit

Permalink
feat(has_around_callbacks): pass arguments to around callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
marian13 committed Feb 5, 2023
1 parent 2d7f720 commit f682f9a
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ module Common
module Plugins
module HasAroundCallbacks
class Middleware < Core::MethodChainMiddleware
def next(...)
include Support::DependencyContainer::Import

import :"entities.Callback", from: Common::Plugins::HasCallbacks::Container

def next(*args, **kwargs, &block)
##
# A variable that stores return value of middleware `chain.next` aka `original_value`.
# It is reassigned later by the `initial_around_callback`.
Expand All @@ -15,14 +19,30 @@ def next(...)
##
# A list of around callbacks.
#
# class Service
# around do |chain|
# # part before `chain.yield`
# original_value = chain.yield
# # part after `chain.yield`
# end
# end
#
# class Service
# around do |chain, arguments|
# # part before `chain.yield`
# original_value = chain.yield
# # part after `chain.yield`
# end
# end
#
around_callbacks = entity.callbacks.for([:around, method])

##
#
#
initial_around_callback = Plugins::HasCallbacks::Entities::Callback.new(
initial_around_callback = entities.Callback.new(
types: [:around, method],
block: proc { original_value = chain.next(...) }
block: proc { original_value = chain.next(*args, **kwargs, &block) }
)

##
Expand Down Expand Up @@ -76,7 +96,7 @@ def next(...)
# rubocop:disable Style/Semicolon
composed =
around_callbacks.reverse.reduce(initial_around_callback) do |composed, callback|
proc { callback.call_in_context(entity, composed); original_value }
proc { callback.call_in_context_with_value_and_arguments(entity, composed, *args, **kwargs, &block); original_value }
end
# rubocop:enable Style/Semicolon

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,41 @@ def result
end
end
end

example_group "method arguments" do
subject(:method_value) { method.call(*args, **kwargs, &block) }

let(:args) { [:foo] }
let(:kwargs) { {foo: :bar} }
let(:block) { proc { :foo } }

let(:service_class) do
Class.new.tap do |klass|
klass.class_exec(result_original_value, out) do |result_original_value, out|
include ConvenientService::Common::Plugins::HasCallbacks::Concern
include ConvenientService::Common::Plugins::HasAroundCallbacks::Concern

define_method(:result) { |*args, **kwargs, &block| result_original_value }
end
end
end

example_group "before callbacks method arguments" do
before do
service_class.around(:result) do |chain, arguments|
raise if arguments.args != [:foo]
raise if arguments.kwargs != {foo: :bar}
raise if arguments.block.call != :foo

chain.yield
end
end

it "passes chain and args, kwargs, block as arguments object" do
expect { method_value }.not_to raise_error
end
end
end
end
end
end
Expand Down

0 comments on commit f682f9a

Please sign in to comment.