Skip to content

Commit

Permalink
always pass Spy::MethodCall to callbacks registered with Spy::Instance
Browse files Browse the repository at this point in the history
  • Loading branch information
jbodah committed Feb 9, 2016
1 parent 5b26bfc commit 2cb3117
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 16 deletions.
30 changes: 23 additions & 7 deletions lib/spy/instance/api/internal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ def call(receiver, *args, &block)
if !is_active
call_original(receiver, *args, &block)
else
@before_callbacks.each {|f| f.call(receiver, *args)}
if @before_callbacks.any?
mc = build_method_call(receiver, *args, &block)
@before_callbacks.each {|f| f.call(mc)}
end

if @around_procs.any?
# Procify the original call
Expand All @@ -43,33 +46,46 @@ def call(receiver, *args, &block)
result = call_and_record(receiver, *args, &block)
end

mc = build_method_call(receiver, *args, &block)

# Keep wrapping the original proc with each around_proc
@around_procs.reduce(original_proc) do |p, wrapper|
Proc.new { wrapper.call receiver, *args, &p }
Proc.new { wrapper.call mc, &p }
end.call
else
result = call_and_record(receiver, *args, &block)
end

@after_callbacks.each {|f| f.call(receiver, *args)}
if @after_callbacks.any?
mc = build_method_call(receiver, *args, &block)
@after_callbacks.each {|f| f.call(mc)}
end

result
end
end

private

def build_method_call(receiver, *args, &block)
Spy::MethodCall.new(
proc { call_original(receiver, *args, &block) },
original.name,
receiver,
*args,
&block)
end

def call_and_record(receiver, *args, &block)
record = track_call(receiver, *args, &block)
result = call_original(receiver, *args, &block)
record.result = result
end

def track_call(receiver, *args, &block)
replayer = proc { call_original(receiver, *args, &block) }
record = Spy::MethodCall.new(replayer, original.name, receiver, *args, &block)
@call_history << record
record
build_method_call(receiver, *args, &block).tap do |mc|
@call_history << mc
end
end

def call_original(receiver, *args, &block)
Expand Down
36 changes: 30 additions & 6 deletions test/before_after_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,25 @@ class BeforeAfterTest < Minitest::Spec
arr = []
spy = Spy.on(arr, :<<)
called_args = nil
spy.before do |receiver, *args|
assert_equal arr, receiver
called_args = *args
spy.before do |mc|
assert_equal arr, mc.receiver
called_args = *mc.args
end
arr << 'a'
assert_equal ['a'], called_args
end

it 'passes a Spy::MethodCall to the block' do
obj = []
spy = Spy.on(obj, :<<)

yielded = nil
spy.before { |mc| yielded = mc }

obj << "hello"

assert yielded.is_a? Spy::MethodCall
end
end

describe 'Spy#after' do
Expand All @@ -36,12 +48,24 @@ class BeforeAfterTest < Minitest::Spec
arr = []
spy = Spy.on(arr, :<<)
called_args = nil
spy.after do |receiver, *args|
assert_equal arr, receiver
called_args = *args
spy.after do |mc|
assert_equal arr, mc.receiver
called_args = *mc.args
end
arr << 'a'
assert_equal ['a'], called_args
end

it 'passes a Spy::MethodCall to the block' do
obj = []
spy = Spy.on(obj, :<<)

yielded = nil
spy.after { |mc| yielded = mc }

obj << "hello"

assert yielded.is_a? Spy::MethodCall
end
end
end
18 changes: 15 additions & 3 deletions test/wrap_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ def hello
obj = Object.new.tap {|o| o.instance_eval { def say(*args); end }}
s = Spy.on(obj, :say)
passed_args = [1, 2, 3]
s.wrap do |reciever, *args|
assert_equal obj, reciever
assert_equal passed_args, args
s.wrap do |mc|
assert_equal obj, mc.receiver
assert_equal passed_args, mc.args
end
obj.say(*passed_args)
end
Expand All @@ -103,6 +103,18 @@ def hello
end
assert_equal 4, r.recursive_add(2,2)
end

it 'passes a Spy::MethodCall to the block' do
obj = []
spy = Spy.on(obj, :<<)

yielded = nil
spy.wrap { |mc| yielded = mc }

obj << "hello"

assert yielded.is_a? Spy::MethodCall
end
end
end
end

0 comments on commit 2cb3117

Please sign in to comment.