diff --git a/Changelog.md b/Changelog.md index fbd91d7b5..8389d6774 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,8 @@ Bug Fixes: * Fix `ActiveRecord::TestFixture#uses_transaction` by using example description to replace example name rather than example in our monkey patched `run_in_transaction?` method. (Stan Lo, #2495) +* Prevent keyword arguments being lost when methods are invoked dynamically + in controller specs. (Josh Cheek, #2509, #2514) ### 5.0.1 / 2021-03-18 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v5.0.0...v5.0.1) diff --git a/lib/rspec/rails/example/controller_example_group.rb b/lib/rspec/rails/example/controller_example_group.rb index 3150f3d46..636a194a1 100644 --- a/lib/rspec/rails/example/controller_example_group.rb +++ b/lib/rspec/rails/example/controller_example_group.rb @@ -176,6 +176,7 @@ def method_missing(method, *args, &block) super end end + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) included do subject { controller } diff --git a/spec/rspec/rails/example/controller_example_group_spec.rb b/spec/rspec/rails/example/controller_example_group_spec.rb index 56b53049d..fa524b0fc 100644 --- a/spec/rspec/rails/example/controller_example_group_spec.rb +++ b/spec/rspec/rails/example/controller_example_group_spec.rb @@ -19,6 +19,23 @@ def group_for(klass) expect(group.included_modules).to include(RSpec::Rails::Matchers::RoutingMatchers) end + it "handles methods invoked via `method_missing` that use keywords" do + group = + RSpec::Core::ExampleGroup.describe ApplicationController do + def a_method(value:); value; end + def method_missing(_name, *_args, **kwargs, &_block); a_method(**kwargs); end + + # This example requires prepend so that the `method_missing` definition + # from `ControllerExampleGroup` bubbles up to our artificial one, in reality + # this is likely to be either an internal RSpec dispatch or one from a 3rd + # party gem. + prepend ControllerExampleGroup + end + example = group.new + + expect(example.call_a_method(value: :value)).to eq :value + end + context "with implicit subject" do it "uses the controller as the subject" do controller = double('controller')