From 794891a82cc238044c140ff9cc89702c48a22dc6 Mon Sep 17 00:00:00 2001 From: Jose M Date: Tue, 26 Nov 2024 13:57:51 +0100 Subject: [PATCH 1/3] Allow to override parents defined hooks --- lib/captain_hook.rb | 18 ++++++++++-------- spec/captain_hook_spec.rb | 8 +++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/captain_hook.rb b/lib/captain_hook.rb index dad1b0a..964702f 100644 --- a/lib/captain_hook.rb +++ b/lib/captain_hook.rb @@ -44,17 +44,19 @@ def hook( # Hooks logic part #### def get_hooks(kind) - # Only get hooks from the most specific class that defines them - return hooks[kind].values if hooks[kind].any? + hook_list = Hash.new { |h, k| h[k] = [] } - # If no hooks defined in this class, look up the inheritance chain - ancestors[1..].each do |ancestor| - next unless ancestor.respond_to?(:hooks) - return ancestor.hooks[kind].values if ancestor.hooks[kind].any? + # Collect hooks from the current class and ancestor classes + [self, *ancestors[1..]].each do |klass| + next unless klass.respond_to?(:hooks) + + (klass.hooks[kind] || {}).each_value do |hook| + hook_list[hook.hook.class] << hook + end end - # If no hooks found anywhere in the chain, return empty array - [] + # Return an array containing the first element of each key in hook_list + hook_list.values.map(&:first) end def hooks diff --git a/spec/captain_hook_spec.rb b/spec/captain_hook_spec.rb index 67242f8..363f77e 100644 --- a/spec/captain_hook_spec.rb +++ b/spec/captain_hook_spec.rb @@ -64,12 +64,9 @@ class ResourceWithHooks [args, {}] } - hook :around, - include: %i[prepare], - hook: ServeHook.new hook :around, - include: %i[serve foo], + include: %i[serve foo prepare], hook: ServeHook.new, skip_when: SkipWhenProc @@ -97,6 +94,8 @@ def policy_context end class ResourceChildWithHooks < ResourceWithHooks + hook :before, include: [:deliver], hook: ErroringHook.new + def foo(dto:); end def prepare(dto:) @@ -124,7 +123,6 @@ def prepare(dto:) expect_any_instance_of(PrepareHook).to receive(:call).once.and_call_original expect_any_instance_of(BeforeAllHook).to receive(:call).once.and_call_original expect_any_instance_of(ManyParametersHook).to receive(:call).once.and_call_original - expect_any_instance_of(ServeHook).to receive(:call).once.and_call_original expect(subject.prepare(dto: "bar")).to eq("preparing bar") end From 7c31962d8067eb109564b620442da64e87617974 Mon Sep 17 00:00:00 2001 From: Jose M Date: Thu, 28 Nov 2024 13:30:59 +0100 Subject: [PATCH 2/3] consider around while excluding --- lib/captain_hook.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/captain_hook.rb b/lib/captain_hook.rb index 964702f..1624ee7 100644 --- a/lib/captain_hook.rb +++ b/lib/captain_hook.rb @@ -72,7 +72,8 @@ def overriden?(method) def method_excluded_by_all_hooks?(method) get_hooks(:before).all? { |hook| hook.exclude.include?(method) } && - get_hooks(:after).all? { |hook| hook.exclude.include?(method) } + get_hooks(:after).all? { |hook| hook.exclude.include?(method) } && + get_hooks(:around).all? { |hook| hook.exclude.include?(method) } end def method_added(method_name) From d88f2511cd2fd886395a7d95ae9df9796506b38a Mon Sep 17 00:00:00 2001 From: Jose M Date: Fri, 29 Nov 2024 11:11:39 +0100 Subject: [PATCH 3/3] Simplify get_hooks method --- lib/captain_hook.rb | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/captain_hook.rb b/lib/captain_hook.rb index 1624ee7..e1f3461 100644 --- a/lib/captain_hook.rb +++ b/lib/captain_hook.rb @@ -44,19 +44,13 @@ def hook( # Hooks logic part #### def get_hooks(kind) - hook_list = Hash.new { |h, k| h[k] = [] } - - # Collect hooks from the current class and ancestor classes - [self, *ancestors[1..]].each do |klass| + ancestors.each_with_object({}) do |klass, hook_list| next unless klass.respond_to?(:hooks) - (klass.hooks[kind] || {}).each_value do |hook| - hook_list[hook.hook.class] << hook + klass.hooks[kind]&.each_value do |hook| + hook_list[hook.hook.class] ||= hook end - end - - # Return an array containing the first element of each key in hook_list - hook_list.values.map(&:first) + end.values end def hooks