Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent should from circumventing target check #2800

Merged
merged 1 commit into from
Jan 26, 2021

Conversation

pirj
Copy link
Member

@pirj pirj commented Dec 15, 2020

By directly instantiating expectation handler, should/should_not was circumventing enforce_value_expectation check.

subject(:action) { -> { raise } }
it { should raise_error StandardError }

would not print "The implicit block expectation syntax is deprecated", while

subject(:action) { -> { raise } }
it { is_expected.to raise_error StandardError }

will.

See rspec/rspec-expectations#1139

@pirj pirj self-assigned this Dec 15, 2020
@@ -78,7 +78,7 @@ def subject
# @note If you are using RSpec's newer expect-based syntax you may
# want to use `is_expected.to` instead of `should`.
def should(matcher=nil, message=nil)
RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message)
is_expected.to(matcher, message)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think the reason why this was the way it was, is because expect can be disabled

Copy link
Member Author

@pirj pirj Dec 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be yet another reason. should/should_not support OperatorMatcher, while is_expected.to does not, due to its prevent_operator_matchers check.

Not sure about the reasoning behind this, probably it does not read right, e.g. it is expected to > 0. Obviously, it is expected to be > 0 sounds better.
However, it should > 0 isn't easy on the ear either.

I intend to assume that should always represents the value expectation syntax, and:

This will print a warning for:

subject(:action) { -> { raise } }
it { should raise_error StandardError }

but the following will continue working:

it { should > 3 }

@JonRowe @benoittgt Is this a correct approach?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also love to move should/should_not/is_expected to rspec-expectations in a follow-up. Can you think of some implications to that? All of them imply that:

This only works if you are using rspec-expectations

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be now is a good moment to:

  • deprecate should with OperatorMatcher
  • retire OperatorMatcher

since BeComparedTo does this job anyway with better readability.

WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With should being removed there is no need to deprecate a specific matcher with it.

@pirj pirj force-pushed the streamline-should-oneliners branch from 64b7ad3 to 13ebc90 Compare December 19, 2020 21:31
@pirj pirj requested a review from JonRowe December 19, 2020 21:32
@pirj
Copy link
Member Author

pirj commented Dec 19, 2020

Update: I've used a different approach - checking for a value matching support of matchers passed to should/should_not.

@pirj pirj force-pushed the streamline-should-oneliners branch 2 times, most recently from 11091a1 to 2403584 Compare December 21, 2020 23:14
@pirj
Copy link
Member Author

pirj commented Dec 22, 2020

I give up on Travis.

@pirj
Copy link
Member Author

pirj commented Dec 23, 2020

This redundant as the whole should is deprecated and will be removed.

@pirj pirj closed this Dec 23, 2020
@JonRowe JonRowe reopened this Dec 23, 2020
@JonRowe
Copy link
Member

JonRowe commented Dec 23, 2020

Reopened because we still need to deprecate this for 3.11, to be merged with rspec/rspec-expectations#1139

@pirj pirj mentioned this pull request Dec 23, 2020
53 tasks
@pirj pirj added this to the 4.0 milestone Dec 25, 2020
@pirj
Copy link
Member Author

pirj commented Jan 25, 2021

@JonRowe ok to merge this?

Comment on lines 151 to 156
matcher_supports_value_expectations = begin
matcher.supports_value_expectations?
rescue
true
end
return if matcher_supports_value_expectations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just looks ugly 😂 , WDYT about extracting the block to a method e.g:

Suggested change
matcher_supports_value_expectations = begin
matcher.supports_value_expectations?
rescue
true
end
return if matcher_supports_value_expectations
return if matcher_supports_value_expectations?

and elsewhere:

      # @private
      def  matcher_supports_value_expectations?
        matcher.supports_value_expectations?
      rescue
        true
      end

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No objections. Especially since enforce_value_expectation will remain only in RSpec 3.x, and will be removed along with should in 4.
Fixed.

@pirj pirj force-pushed the streamline-should-oneliners branch from eebc91e to 9886b8c Compare January 26, 2021 13:50
By directly instantiating expectation handler, should/should_not was
circumventing enforce_value_expectation check.

    subject(:action) { -> { raise } }
    it { should raise_error StandardError }

would not print "The implicit block expectation syntax is deprecated",
while

    subject(:action) { -> { raise } }
    it { is_expected.to raise_error StandardError }

will.

See rspec/rspec-expectations#1139
@pirj pirj force-pushed the streamline-should-oneliners branch from d7c9001 to d04af61 Compare January 26, 2021 14:03
@pirj pirj merged commit e95cfe3 into main Jan 26, 2021
@JonRowe JonRowe deleted the streamline-should-oneliners branch January 30, 2021 11:02
yujinakayama pushed a commit to yujinakayama/rspec-monorepo that referenced this pull request Oct 6, 2021
…-should-oneliners

Prevent should from circumventing target check

---
This commit was imported from rspec/rspec-core@e95cfe3.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants