From d68819e5d27190866adc218778b06711b8a7df9b Mon Sep 17 00:00:00 2001 From: Jon Rowe Date: Wed, 8 Apr 2020 18:17:15 +0100 Subject: [PATCH] [expectations] Merge pull request rspec/rspec-expectations#1176 from rspec/fix-kw-args-deprecation-in-dsl Fix Ruby 2.7 keyword args deprecation in DSL --- This commit was imported from https://github.com/rspec/rspec-expectations/commit/fdbf174044b0dcd424b5f239976913bb6b2de7a8. --- rspec-expectations/lib/rspec/matchers/dsl.rb | 10 ++++- .../spec/rspec/matchers/dsl_spec.rb | 40 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/rspec-expectations/lib/rspec/matchers/dsl.rb b/rspec-expectations/lib/rspec/matchers/dsl.rb index f185d9117..1a1f9c50f 100644 --- a/rspec-expectations/lib/rspec/matchers/dsl.rb +++ b/rspec-expectations/lib/rspec/matchers/dsl.rb @@ -1,3 +1,5 @@ +RSpec::Support.require_rspec_support "with_keywords_when_needed" + module RSpec module Matchers # Defines the custom matcher DSL. @@ -460,11 +462,12 @@ def initialize(name, declarations, matcher_execution_context, *expected, &block_ @chained_method_clauses = [] @block_arg = block_arg - class << self + klass = class << self # See `Macros#define_user_override` above, for an explanation. include(@user_method_defs = Module.new) self - end.class_exec(*expected, &declarations) + end + RSpec::Support::WithKeywordsWhenNeeded.class_exec(klass, *expected, &declarations) end # Provides the expected value. This will return an array if @@ -528,6 +531,9 @@ def method_missing(method, *args, &block) super(method, *args, &block) end end + # The method_missing method should be refactored to pass kw args in RSpec 4 + # then this can be removed + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) end end end diff --git a/rspec-expectations/spec/rspec/matchers/dsl_spec.rb b/rspec-expectations/spec/rspec/matchers/dsl_spec.rb index d34f2ee87..e0f98c5cc 100644 --- a/rspec-expectations/spec/rspec/matchers/dsl_spec.rb +++ b/rspec-expectations/spec/rspec/matchers/dsl_spec.rb @@ -29,6 +29,46 @@ def ok expect { matcher_b.i_dont_exist }.to raise_error(NameError) end + if RSpec::Support::RubyFeatures.required_kw_args_supported? + binding.eval(<<-CODE, __FILE__, __LINE__) + it 'supports the use of required keyword arguments in definition block' do + RSpec::Matchers.define(:match_required_kw) do |bar:| + match { expect(actual).to eq bar } + end + expect(1).to match_required_kw(bar: 1) + end + + def kw(a:) + a + end + + it "supports the use of required keyword arguments on methods" do + RSpec::Matchers.define(:matcher_required_kw_on_method) {} + expect(matcher_required_kw_on_method.kw(a: 1)).to eq(1) + end + CODE + end + + if RSpec::Support::RubyFeatures.kw_args_supported? + binding.eval(<<-CODE, __FILE__, __LINE__) + it 'supports the use of optional keyword arguments in definition block' do + RSpec::Matchers.define(:match_optional_kw) do |bar: nil| + match { expect(actual).to eq bar } + end + expect(1).to match_optional_kw(bar: 1) + end + + def optional_kw(a: nil) + a + end + + it "supports the use of optional keyword arguments on methods" do + RSpec::Matchers.define(:matcher_optional_kw_on_method) {} + expect(matcher_optional_kw_on_method.optional_kw(a: 1)).to eq(1) + end + CODE + end + it "clears user instance variables between invocations" do RSpec::Matchers.define(:be_just_like) do |expected| match do |actual|