Skip to content

Commit

Permalink
Handle kwargs seperately for and_call_original in supported rubies
Browse files Browse the repository at this point in the history
  • Loading branch information
JonRowe committed Apr 5, 2020
1 parent a0005a1 commit 18a0c67
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
21 changes: 20 additions & 1 deletion lib/rspec/mocks/message_expectation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def and_return(first_value, *values)
# expect(counter.count).to eq(original_count + 1)
def and_call_original
wrap_original(__method__) do |original, *args, &block|
original.call(*args, &block)
__call_original(original, *args, &block)
end
end

Expand Down Expand Up @@ -354,6 +354,25 @@ def to_s
end
alias inspect to_s

private

if RSpec::Support::RubyFeatures.kw_args_supported?
def __call_original(original, *args, &block)
if RSpec::Support::MethodSignature.new(original).has_kw_args_in?(args)
binding.eval(<<-CODE, __FILE__, __LINE__)
kwargs = args.pop
original.call(*args, **kwargs, &block)
CODE
else
original.call(*args, &block)
end
end
else
def __call_original(original, *args, &block)
original.call(*args, &block)
end
end

# @private
# Contains the parts of `MessageExpectation` that aren't part of
# rspec-mocks' public API. The class is very big and could really use
Expand Down
15 changes: 15 additions & 0 deletions spec/rspec/mocks/and_call_original_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ def meth_2(x)
yield x, :additional_yielded_arg
end

binding.eval(<<-CODE, __FILE__, __LINE__)
def meth_3(keyword_arg: nil)
keyword_arg
end
CODE

def self.new_instance
new
end
Expand Down Expand Up @@ -59,6 +65,15 @@ def self.new_instance
expect(value).to eq([:submitted_arg, :additional_yielded_arg])
end

if RSpec::Support::RubyFeatures.kw_args_supported?
it 'works with keyword arguments' do
expect(instance).to receive(:meth_3).and_call_original
binding.eval(<<-CODE, __FILE__, __LINE__)
expect(instance.meth_3(keyword_arg: :original_arg)).to eq :original_arg
CODE
end
end

it 'errors when you pass through the wrong number of args' do
expect(instance).to receive(:meth_1).and_call_original
expect(instance).to receive(:meth_2).twice.and_call_original
Expand Down

0 comments on commit 18a0c67

Please sign in to comment.