From 7fe00f09f6281660f0beafeb55c7ec79a6938a8e Mon Sep 17 00:00:00 2001 From: Josh Bodah Date: Mon, 6 Jun 2016 17:06:55 -0400 Subject: [PATCH] add a rough Spy::Instance#instead --- lib/spy/instance.rb | 5 +++ lib/spy/instance/api/internal.rb | 12 ++++-- test/instead_test.rb | 74 ++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 test/instead_test.rb diff --git a/lib/spy/instance.rb b/lib/spy/instance.rb index ea982ac..e085818 100644 --- a/lib/spy/instance.rb +++ b/lib/spy/instance.rb @@ -21,6 +21,7 @@ def initialize(spied, original) @around_procs = [] @call_history = [] @strategy = Strategy.factory_build(self) + @instead = nil end def name @@ -67,6 +68,10 @@ def after(&block) self end + def instead(&block) + @instead = block + end + private def extract_visibility diff --git a/lib/spy/instance/api/internal.rb b/lib/spy/instance/api/internal.rb index c2b5759..77bbab2 100644 --- a/lib/spy/instance/api/internal.rb +++ b/lib/spy/instance/api/internal.rb @@ -80,11 +80,15 @@ def build_method_call(receiver, *args, &block) end def call_and_record(receiver, args, opts = {}, &block) - record = opts[:record] || build_method_call(receiver, *args, &block) - @call_history << record + if @instead + @instead.call build_method_call(receiver, *args, &block) + else + record = opts[:record] || build_method_call(receiver, *args, &block) + @call_history << record - result = call_original(receiver, *args, &block) - record.result = result + result = call_original(receiver, *args, &block) + record.result = result + end end def call_original(receiver, *args, &block) diff --git a/test/instead_test.rb b/test/instead_test.rb new file mode 100644 index 0000000..fc49cd6 --- /dev/null +++ b/test/instead_test.rb @@ -0,0 +1,74 @@ +require 'test_helper' + +class InsteadTest < Minitest::Spec + describe 'Spy::Instance#instead' do + after do + Spy.restore(:all) + end + + it 'will run the instead block and not the original call' do + o = Object.new + o.instance_eval do + def incr; total += 1; end + def total; @total ||= 0; end + def total=(n); @total = n; end + end + + Spy.on(o, :incr).instead do |mc| + mc.receiver.total += 2 + end + + o.incr + + assert_equal 2, o.total + end + + it 'will return the value returned by the block' do + o = Object.new + o.instance_eval do + def name; 'josh'; end + end + + Spy.on(o, :name).instead { 'penny' } + + assert_equal 'penny', o.name + end + + it 'plays nicely with Spy::Instance#when' do + o = Object.new + o.instance_eval do + def value=(n); @value = n; end + def value; @value; end + def name; 'josh'; end + end + + Spy.on(o, :name).when { o.value == 0 }.instead { 'penny' } + + o.value = 0 + assert_equal 'penny', o.name + + o.value = 1 + assert_equal 'josh', o.name + end + + it 'allows multiple whens and insteads' do + skip 'havent implemented multiple whens yet' + + o = Object.new + o.instance_eval do + def value=(n); @value = n; end + def value; @value; end + def name; 'josh'; end + end + + Spy.on(o, :name).when { o.value == 0 }.instead { 'penny' } + Spy.on(o, :name).when { o.value == 1 }.instead { 'lauren' } + + o.value = 0 + assert_equal 'penny', o.name + + o.value = 1 + assert_equal 'lauren', o.name + end + end +end