Skip to content

Commit

Permalink
Merge pull request #1485 from rspec/fix-regexp-include-without-count
Browse files Browse the repository at this point in the history
Fix `include(/regexp/)` when used without a count.
  • Loading branch information
JonRowe committed Sep 6, 2024
1 parent af508d2 commit 5c82bd3
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 3 deletions.
6 changes: 5 additions & 1 deletion features/built_in_matchers/include.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Feature: `include` matcher

```ruby
expect("a string").to include("a")
expect("a string").to include(/str..g/)
expect("a string").to include(/a|str/).twice
expect("a string").to include("str", "g")
expect("a string").not_to include("foo")
Expand Down Expand Up @@ -80,22 +81,25 @@ Feature: `include` matcher
RSpec.describe "a string" do
it { is_expected.to include("str") }
it { is_expected.to include("a", "str", "ng") }
it { is_expected.to include(/str..g/) }
it { is_expected.to include(/a|str/).twice }
it { is_expected.not_to include("foo") }
it { is_expected.not_to include("foo", "bar") }
# deliberate failures
it { is_expected.to include("foo") }
it { is_expected.not_to include("str") }
it { is_expected.not_to include(/str..g/) }
it { is_expected.to include("str").at_least(:twice) }
it { is_expected.to include("str", "foo") }
it { is_expected.not_to include("str", "foo") }
end
"""
When I run `rspec string_include_matcher_spec.rb`
Then the output should contain all of these:
| 10 examples, 5 failures |
| 12 examples, 6 failures |
| expected "a string" to include "foo" |
| expected "a string" not to include /str..g/ |
| expected "a string" not to include "str" |
| expected "a string" to include "str" at least twice but it is included once |
| expected "a string" to include "foo" |
Expand Down
2 changes: 2 additions & 0 deletions lib/rspec/matchers/built_in/include.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def actual_hash_has_key?(expected_key)
end

def actual_collection_includes?(expected_item)
return actual.scan(expected_item).size > 0 if Regexp === expected_item && String === actual
return true if actual.include?(expected_item)

# String lacks an `any?` method...
Expand Down Expand Up @@ -200,6 +201,7 @@ def count_inclusions

def diff_would_wrongly_highlight_matched_item?
return false unless actual.is_a?(String) && expected.is_a?(Array)
return false if Regexp === expecteds.first

lines = actual.split("\n")
expected.any? do |str|
Expand Down
12 changes: 10 additions & 2 deletions spec/rspec/matchers/built_in/include_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ def hash.send; :sent; end
expect("abc").to include("a")
end

it "passes if target matches a regexp" do
expect("abc").to include(/[cba]{3}/)
end

it "fails if target does not include expected" do
expect {
expect("abc").to include("d")
Expand All @@ -240,16 +244,20 @@ def hash.send; :sent; end
end

context "with exact count" do
it 'fails if the block yields wrong number of times' do
it 'fails if the string contains the wrong number of occurences' do
expect {
expect('foo bar foo').to include('foo').once
}.to fail_with(/expected "foo bar foo" to include "foo" once but it is included twice/)
expect {
expect('foo bar foo').to include(/[of]{3}/).once
}.to fail_with(/expected "foo bar foo" to include \/\[of\]\{3\}\/ once but it is included twice/)
end

it 'passes if the block yields the specified number of times' do
it 'passes if the string contains the correct number of occurences' do
expect('fooo bar').to include('oo').once
expect('fooo bar').to include('o').thrice
expect('fooo ooo oo bar foo').to include('oo').exactly(4).times
expect('fooo ooo oo bar foo').to include(/fo{2}/).exactly(2).times
end
end

Expand Down

0 comments on commit 5c82bd3

Please sign in to comment.