From 2e7a888f9f75239eeb821d2692f656ff9b8301d6 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Sat, 14 Sep 2024 16:14:07 -0300 Subject: [PATCH] fix: pass_thru behavior when the proc is spec-ed via a Proc as last argument v2.4.1 broke backward compatibility in the following case: with(some, arguments, Proc).pass_thru In that case, the block would be given as positional argument to the original method, instead of being passed as a block. --- lib/flexmock/expectation.rb | 10 ++++++++-- test/partial_mock_test.rb | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/flexmock/expectation.rb b/lib/flexmock/expectation.rb index a985144..b8058c3 100644 --- a/lib/flexmock/expectation.rb +++ b/lib/flexmock/expectation.rb @@ -128,7 +128,7 @@ def return_value(args, block) if @expected_block ret_block.call(*args, &block) - elsif block + elsif block && @expected_block.nil? ret_block.call(*args, block) else ret_block.call(*args) @@ -407,6 +407,12 @@ def pass_thru(&block) block ||= lambda { |value| value } and_return { |*args, &orig_block| begin + if @expected_block.nil? && !orig_block + if Proc === args.last + orig_block = args.last + args = args[0..-2] + end + end block.call(@mock.flexmock_invoke_original(@sym, args, orig_block)) rescue NoMethodError => e if e.name == @sym @@ -414,7 +420,7 @@ def pass_thru(&block) else raise end - end + end } end diff --git a/test/partial_mock_test.rb b/test/partial_mock_test.rb index a340ec6..946cac3 100644 --- a/test/partial_mock_test.rb +++ b/test/partial_mock_test.rb @@ -651,6 +651,20 @@ def mocked_method(&block) assert_equal block, obj.block end + def test_pass_thru_forwards_a_block_if_there_is_no_explicit_absence + obj = Class.new do + attr_reader :block + def mocked_method(&block) + @block = block + end + end.new + flexmock(obj).should_receive(:mocked_method).pass_thru + + block = obj.mocked_method { 42 } + assert_kind_of Proc, block + assert_equal block, obj.block + end + def test_it_checks_whether_mocks_are_forbidden_before_forwarding_the_call obj = Class.new flexmock(obj).should_receive(:mocked).never