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

Implement RSpec/IteratedExpectation cop. Fixes #278 #340

Merged
merged 1 commit into from
Mar 15, 2017
Merged

Implement RSpec/IteratedExpectation cop. Fixes #278 #340

merged 1 commit into from
Mar 15, 2017

Conversation

Darhazer
Copy link
Member

@Darhazer Darhazer commented Mar 3, 2017

@backus

Please look at the examples and let me know if you can think of other examples that we can detect, or some possible false positives.

TODO:

  • Implement autocorrect
  • Multiple expectations can also be converted to all with an and

@Darhazer
Copy link
Member Author

Darhazer commented Mar 9, 2017

Autocorrect could be quite complicated, so I'll leave it for now.

Tested for false positives on rubocop and one more base
I'm not sure for the naming. AllInsteadEach is more descriptive. I'm open for suggestions

Copy link
Collaborator

@bquorning bquorning left a comment

Choose a reason for hiding this comment

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

I’ve left a few comments, but overall it looks fine. I ran it locally, found 3 offenses and no false positives.

expect_no_violations(<<-RUBY)
it 'validates users' do
[user1, user2, user3].each do |user|
allow(Somethig).to receive(:method).and_return(user)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Somethig -> Something

it 'ignores `each` with proc' do
expect_no_violations(<<-RUBY)
it 'validates users' do
[user1, user2, user3].each(&:to_s)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since this proc also doesn’t set an expectation, isn’t this case covered in the following spec (line 30)?

it 'flags `each` when expectation calls method with arguments' do
expect_violation(<<-RUBY)
it 'validates users' do
[user1, user2, user3].each { |user| expect(user).to be_an(User) }
Copy link
Collaborator

Choose a reason for hiding this comment

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

be_an -> be_a

# it 'validates users' do
# expect([user1, user2, user3]).to all(be_valid)
# end
class Each < Cop
Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree that Each is too generic a name. IteratedExpectation is the best I can think of right now, and I don’t really like that either. Perhaps @backus can think of a better name?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe AllMatcher? I usually like looking at the rspec internal naming but it isn't super helpful in this case heh https://github.com/rspec/rspec-expectations/blob/82ab90b513dfcd0b52064f56be4b2c6218adeded/lib/rspec/matchers.rb#L638-L655

Copy link
Contributor

Choose a reason for hiding this comment

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

I think IteratedExpectation is actually a pretty reasonable name. Since we may possibly have cops in the future relating to the all matcher, AllMatcher may be too general also.

Copy link
Collaborator

@backus backus Mar 10, 2017

Choose a reason for hiding this comment

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

If our intention is to have multiple cops that recommend the all(...) matched then I agree. That also seems pretty reasonable given that it can have pretty complex usage

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, i just think it's definitely possible if not likely. There's already a few cops (for instance the ItBehavesLike cop i just added...) that cover lots of potential recommendations (who's to say we won't have more corrections for using it_behaves_like in the future) so I think we should start being more careful about how we name new cops.

At the risk of going slightly off topic, there's also #232 to consider at some point. Idk if I'm sold on it exactly, but another area where this was slightly awkward recently was adding a new feature to the ExampleWording cop. It didn't make sense to add a second wording cop but the two features inside there now would probably be in separate cops and individually configurable, in an ideal world.

def on_block(node)
each?(node) do |arg, body|
if single_expectation?(body, arg) || only_expectations?(body, arg)
@arg = arg
Copy link
Collaborator

Choose a reason for hiding this comment

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

What does setting @arg do?

Copy link
Member Author

Choose a reason for hiding this comment

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

left over from some initial attempts to implement autocorrect. Its not needed, as arg can be retrieved from the node itself, but I have dropped the autocorrect support completely. I'll clean up

@Darhazer
Copy link
Member Author

PR updated

@Darhazer Darhazer changed the title Implement RSpec/Each cop. Fixes #278 Implement RSpec/IteratedExpectation cop. Fixes #278 Mar 10, 2017
@backus
Copy link
Collaborator

backus commented Mar 15, 2017

Looks great! Thanks @Darhazer

@backus backus merged commit 5adddf9 into rubocop:master Mar 15, 2017
markburns pushed a commit to markburns/rubocop-rails-ddd that referenced this pull request Nov 7, 2017
Implement RSpec/IteratedExpectation cop. Fixes rubocop#278
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.

None yet

4 participants