Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyword argument expectation matching failing in Ruby 2.7 #1457

Closed
marcotc opened this issue Jan 29, 2022 · 2 comments
Closed

Keyword argument expectation matching failing in Ruby 2.7 #1457

marcotc opened this issue Jan 29, 2022 · 2 comments

Comments

@marcotc
Copy link

marcotc commented Jan 29, 2022

Subject of the issue

When upgrading to 3.10.3 today, I noticed one test failure in our CI matrix that only affected Ruby 2.7.

This issue happens when we provide an empty keyword argument Hash as a keyword splat argument (method(**{})) to RSpec::Mocks::Matchers::Receive#with. Example: expect(obj).to receive(:call).with(:foo, **{}).

When later invoking obj.call(:foo, **{}) I receive the expected: (:foo, {}) got: (:foo) assertion error.

This does not affect Ruby < 2.7, nor Ruby > 2.7. Nor it affects rspec-mocks 3.10.2.

Preliminary investigation

Looking at the changelog for v3.10.3, I can see changes around ruby2_keywords, and it looks like the empty keyword argument {} get dropped in this invocation:

method_double.proxy_method_invoked(self, *args, &block)

Another option is to filter out the empty hash before is gets stored in the args here:

@recorded_customizations << ExpectationCustomization.new(msg, args, block)

I'm not sure which of these avenues is the correct one, though.

Your environment

  • Ruby version: 2.7.3p183
  • rspec-mocks version: 3.10.3

Steps to reproduce

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'rspec', '3.10.0'
  gem 'rspec-mocks', '3.10.3'
end

require 'rspec/autorun'

RSpec.describe do
  it do
    obj = Object.new
    expect(obj).to receive(:call).with(:foo, **{})
    obj.call(:foo, **{})
  end
end

Expected behavior

Assertion to match, and test to pass:

Finished in 0.00839 seconds (files took 0.08246 seconds to load)
1 example, 0 failures

Actual behavior

  1) is expected to receive call(:foo, {}) 1 time
     Failure/Error: obj.call(:foo, **{})

       #<Object:0x000055fe45517ba8> received :call with unexpected arguments
         expected: (:foo, {})
              got: (:foo)
     # test.rb:15:in `block (2 levels) in <main>'
@pirj
Copy link
Member

pirj commented Jan 29, 2022 via email

@marcotc
Copy link
Author

marcotc commented Apr 26, 2023

This is fixed in 3.12.0, thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants