Skip to content
This repository has been archived by the owner on Nov 30, 2024. It is now read-only.

Delegate kwargs when defining a method with chain #1374

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
### Development
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.0...main)

Bug Fixes:

* Fix keyword arguments delegation for `chain` in custom matchers. (Tyler Rick, #1374)

### 3.12.0 / 2022-10-26
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.1...v3.12.0)

Expand Down
1 change: 1 addition & 0 deletions lib/rspec/matchers/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ def chain(method_name, *attr_names, &definition)
@chained_method_clauses.push([method_name, args])
self
end
ruby2_keywords method_name if respond_to?(:ruby2_keywords, true)
end

def assign_attributes(attr_names)
Expand Down
42 changes: 35 additions & 7 deletions spec/rspec/matchers/dsl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,17 @@ def new_matcher(name, *expected, &block)
(to_match <= five) || greater_than_ceiling(to_match) && not_divisible_by_divisor?(to_match)
end

chain :and_smaller_than do |ceiling|
@ceiling = ceiling
if RSpec::Support::RubyFeatures.kw_args_supported?
binding.eval(<<-CODE, __FILE__, __LINE__)
chain :and_smaller_than do |ceiling, inclusive: false|
@ceiling = ceiling
@ceiling_inclusive = inclusive
end
CODE
else
chain :and_smaller_than do |ceiling|
@ceiling = ceiling
end
end

chain :and_divisible_by do |divisor|
Expand All @@ -364,20 +373,30 @@ def new_matcher(name, *expected, &block)

private

def smaller_than_ceiling?(to_match)
to_match < @ceiling
if RSpec::Support::RubyFeatures.kw_args_supported?
def smaller_than_ceiling?(to_match)
if @ceiling_inclusive
to_match <= @ceiling
else
to_match < @ceiling
end
end
else
def smaller_than_ceiling?(to_match)
to_match < @ceiling
end
end

def greater_than_ceiling(to_match)
to_match >= @ceiling
end

def divisible_by_divisor?(to_match)
@divisor % to_match == 0
to_match % @divisor == 0
end

def not_divisible_by_divisor?(to_match)
@divisor % to_match != 0
to_match % @divisor != 0
end
end
end
Expand All @@ -397,7 +416,7 @@ def not_divisible_by_divisor?(to_match)
expect { expect(8).to match }.to fail_with 'expected 8 to be bigger than 5'
end

it "provides a default negative expectation failure message that does not include the any of the chained matchers's descriptions" do
it "provides a default negative expectation failure message that does not include any of the chained matchers' descriptions" do
expect { expect(9).to_not match }.to fail_with 'expected 9 not to be bigger than 5'
end
end
Expand All @@ -421,6 +440,15 @@ def not_divisible_by_divisor?(to_match)
expect { expect(21).to_not matcher.and_smaller_than(29).and_divisible_by(3) }.to \
fail_with 'expected 21 not to be bigger than 5 and smaller than 29 and divisible by 3'
end

if RSpec::Support::RubyFeatures.kw_args_supported?
binding.eval(<<-CODE, __FILE__, __LINE__)
it "allows passing keyword args to chain block" do
match = matcher.and_smaller_than(10, inclusive: true).and_divisible_by(1)
expect(10).to match
end
CODE
end
end

it 'only decides if to include the chained clauses at the time description is invoked' do
Expand Down