Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions lib/captain_hook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,13 @@ 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?
ancestors.each_with_object({}) do |klass, hook_list|
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

much better!

next unless klass.respond_to?(:hooks)

# 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?
end

# If no hooks found anywhere in the chain, return empty array
[]
klass.hooks[kind]&.each_value do |hook|
hook_list[hook.hook.class] ||= hook
end
end.values
end

def hooks
Expand All @@ -70,7 +66,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)
Expand Down
8 changes: 3 additions & 5 deletions spec/captain_hook_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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:)
Expand Down Expand Up @@ -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
Expand Down