Skip to content

Commit

Permalink
Merge 4b5b7b5 into ee347a7
Browse files Browse the repository at this point in the history
  • Loading branch information
jbodah committed Feb 9, 2016
2 parents ee347a7 + 4b5b7b5 commit 75a8815
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 36 deletions.
64 changes: 37 additions & 27 deletions lib/spy/instance/api/internal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,46 +30,56 @@ def call(receiver, *args, &block)
# it isn't just a data struct
is_active = @conditional_filters.all? {|f| f.call(receiver, *args)}

if !is_active
call_original(receiver, *args, &block)
else
@before_callbacks.each {|f| f.call(receiver, *args)}
return call_original(receiver, *args, &block) if !is_active

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
# Still return the result from it
result = nil
original_proc = Proc.new do
result = call_and_record(receiver, *args, &block)
end
if @around_procs.any?
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 }
end.call
else
result = call_and_record(receiver, *args, &block)
# Procify the original call
# Still return the result from it
result = nil
original_proc = Proc.new do
result = call_and_record(receiver, args, { :record => mc }, &block)
end

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

result
if @after_callbacks.any?
mc = @call_history.last
@after_callbacks.each {|f| f.call(mc)}
end

result
end

private

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

def track_call(receiver, *args, &block)
replayer = proc { call_original(receiver, *args, &block) }
record = Spy::MethodCall.new(replayer, original.name, receiver, *args, &block)
def call_and_record(receiver, args, opts = {}, &block)
record = opts[:record] || build_method_call(receiver, *args, &block)
@call_history << record
record

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

def call_original(receiver, *args, &block)
Expand Down
48 changes: 42 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,36 @@ 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

it 'has the Spy::MethodCall result field filled in' do
obj = []
spy = Spy.on(obj, :<<)

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

obj << "hello"

assert_equal obj, yielded.result
end
end
end
30 changes: 27 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,30 @@ 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

it 'fills in the Spy::MethodCall result field after yielding execution back to the spied method' do
obj = []
spy = Spy.on(obj, :<<)

yielded = nil
spy.wrap { |mc, &block| block.call; yielded = mc }

obj << "hello"

assert_equal obj, yielded.result
end
end
end
end

0 comments on commit 75a8815

Please sign in to comment.