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

Commit e95cfe3

Browse files
authored
Merge pull request #2800 from rspec/streamline-should-oneliners
Prevent should from circumventing target check
2 parents bea9f5e + d04af61 commit e95cfe3

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

lib/rspec/core/memoized_helpers.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def subject
7878
# @note If you are using RSpec's newer expect-based syntax you may
7979
# want to use `is_expected.to` instead of `should`.
8080
def should(matcher=nil, message=nil)
81+
enforce_value_expectation(matcher, 'should')
8182
RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message)
8283
end
8384

@@ -97,6 +98,7 @@ def should(matcher=nil, message=nil)
9798
# @note If you are using RSpec's newer expect-based syntax you may
9899
# want to use `is_expected.to_not` instead of `should_not`.
99100
def should_not(matcher=nil, message=nil)
101+
enforce_value_expectation(matcher, 'should_not')
100102
RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message)
101103
end
102104

@@ -144,6 +146,26 @@ def __init_memoized
144146
end
145147
end
146148

149+
# @private
150+
def enforce_value_expectation(matcher, method_name)
151+
return if matcher_supports_value_expectations?(matcher)
152+
153+
RSpec.deprecate(
154+
"#{method_name} #{RSpec::Support::ObjectFormatter.format(matcher)}",
155+
:message =>
156+
"The implicit block expectation syntax is deprecated, you should pass " \
157+
"a block to `expect` to use the provided block expectation matcher " \
158+
"(#{RSpec::Support::ObjectFormatter.format(matcher)}), " \
159+
"or the matcher must implement `supports_value_expectations?`."
160+
)
161+
end
162+
163+
def matcher_supports_value_expectations?(matcher)
164+
matcher.supports_value_expectations?
165+
rescue
166+
true
167+
end
168+
147169
# @private
148170
class ThreadsafeMemoized
149171
def initialize

spec/rspec/core/memoized_helpers_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,28 @@ def hello_message; "Hello from module"; end
630630
end
631631
end
632632

633+
RSpec.describe 'implicit block expectation syntax' do
634+
matcher :block_matcher do
635+
match { |actual| true }
636+
supports_block_expectations
637+
def supports_value_expectations?
638+
false
639+
end
640+
end
641+
642+
subject { 'value or a Proc' }
643+
644+
it '`should` prints a deprecation warning when given a value' do
645+
expect_warn_deprecation(/The implicit block expectation syntax is deprecated, you should pass/)
646+
expect { should block_matcher }.not_to raise_error
647+
end
648+
649+
it '`should_not` prints a deprecation warning when given a value' do
650+
expect_warn_deprecation(/The implicit block expectation syntax is deprecated, you should pass/)
651+
expect { should_not block_matcher }.to raise_error(Exception)
652+
end
653+
end
654+
633655
RSpec.describe 'Module#define_method' do
634656
it 'retains its normal private visibility on Ruby versions where it is normally private', :if => RUBY_VERSION < '2.5' do
635657
a_module = Module.new

0 commit comments

Comments
 (0)