class Spy::Instance
Attributes
call_history[R]
original[R]
spied[R]
strategy[R]
Public Class Methods
new(blueprint)
click to toggle source
# File lib/spy/instance.rb, line 13 def initialize(blueprint) original = case blueprint.type when :dynamic_delegation FakeMethod.new(blueprint.msg) { |*args, &block| blueprint.target.method_missing(blueprint.msg, *args, &block) } when :instance_method blueprint.target.instance_method(blueprint.msg) else blueprint.target.method(blueprint.msg) end @original = original @spied = blueprint.target @strategy = choose_strategy(blueprint) @call_history = [] @internal = {} @internal[:conditional_filters] = [] @internal[:before_callbacks] = [] @internal[:after_callbacks]= [] @internal[:around_procs] = [] @internal[:instead]= nil end
Public Instance Methods
after(&block)
click to toggle source
# File lib/spy/instance.rb, line 76 def after(&block) @internal[:after_callbacks] << block self end
apply(method_call)
click to toggle source
@private
# File lib/spy/instance.rb, line 100 def apply(method_call) return method_call.call_original unless passes_all_conditions?(method_call) result = nil runner = if @internal[:instead] proc do @call_history << method_call result = @internal[:instead].call(method_call) end else proc do @call_history << method_call result = method_call.call_original(true) end end if @internal[:around_procs].any? runner = @internal[:around_procs].reduce(runner) do |p, wrapper| proc { wrapper[method_call, &p] } end end run_before_callbacks(method_call) runner.call run_after_callbacks(method_call) result end
before(&block)
click to toggle source
# File lib/spy/instance.rb, line 71 def before(&block) @internal[:before_callbacks] << block self end
call_count()
click to toggle source
# File lib/spy/instance.rb, line 41 def call_count @call_history.size end
call_original(*args)
click to toggle source
@private
# File lib/spy/instance.rb, line 91 def call_original(*args) if original.is_a?(UnboundMethod) call_original_unbound_method(*args) else call_original_method(*args) end end
called?()
click to toggle source
# File lib/spy/instance.rb, line 86 def called? @call_history.any? end
instead(&block)
click to toggle source
# File lib/spy/instance.rb, line 81 def instead(&block) @internal[:instead] = block self end
name()
click to toggle source
# File lib/spy/instance.rb, line 37 def name @original.name end
replay_all()
click to toggle source
# File lib/spy/instance.rb, line 45 def replay_all @call_history.map(&:replay) end
start()
click to toggle source
# File lib/spy/instance.rb, line 49 def start @strategy.apply self end
stop()
click to toggle source
# File lib/spy/instance.rb, line 54 def stop @strategy.undo self end
when(&block)
click to toggle source
# File lib/spy/instance.rb, line 59 def when(&block) @internal[:conditional_filters] << block self end
wrap(&block)
click to toggle source
Expect block to yield. Call the rest of the chain when it does
# File lib/spy/instance.rb, line 66 def wrap(&block) @internal[:around_procs] << block self end
Private Instance Methods
call_original_method(_receiver, args, block)
click to toggle source
# File lib/spy/instance.rb, line 150 def call_original_method(_receiver, args, block) original.call(*args, &block) end
call_original_unbound_method(receiver, args, block)
click to toggle source
# File lib/spy/instance.rb, line 146 def call_original_unbound_method(receiver, args, block) original.bind(receiver).call(*args, &block) end
choose_strategy(blueprint)
click to toggle source
# File lib/spy/instance.rb, line 154 def choose_strategy(blueprint) if blueprint.type == :dynamic_delegation Strategy::Intercept.new(self) elsif @original.owner == @spied || @original.owner == @spied.singleton_class Strategy::Wrap.new(self) else Strategy::Intercept.new(self) end end
passes_all_conditions?(method_call)
click to toggle source
# File lib/spy/instance.rb, line 134 def passes_all_conditions?(method_call) @internal[:conditional_filters].all? { |f| f[method_call] } end
run_after_callbacks(method_call)
click to toggle source
# File lib/spy/instance.rb, line 142 def run_after_callbacks(method_call) @internal[:after_callbacks].each { |f| f[method_call] } end
run_before_callbacks(method_call)
click to toggle source
# File lib/spy/instance.rb, line 138 def run_before_callbacks(method_call) @internal[:before_callbacks].each { |f| f[method_call] } end