From 9bd3ccc4b82c4cec2c3dd29fa5a087fe134894b7 Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Thu, 20 May 2021 02:53:48 +0530 Subject: [PATCH] Fix false negative for `RSpec/ExpectChange` cop for block style with chained method call Closes #1143 --- CHANGELOG.md | 2 ++ lib/rubocop/cop/rspec/expect_change.rb | 7 +++---- spec/rubocop/cop/rspec/expect_change_spec.rb | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf5e082ab..7662ea63c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Master (Unreleased) +* Fix false negative for `RSpec/ExpectChange` cop for block style with chained method call. ([@tejasbubane][]) + ## 2.3.0 (2021-04-28) * Allow `RSpec/ContextWording` to accept multi-word prefixes. ([@hosamaly][]) diff --git a/lib/rubocop/cop/rspec/expect_change.rb b/lib/rubocop/cop/rspec/expect_change.rb index 7c95b772b..2c5208616 100644 --- a/lib/rubocop/cop/rspec/expect_change.rb +++ b/lib/rubocop/cop/rspec/expect_change.rb @@ -39,7 +39,7 @@ class ExpectChange < Base # @!method expect_change_with_arguments(node) def_node_matcher :expect_change_with_arguments, <<-PATTERN - (send nil? :change ({const send} nil? $_) (sym $_)) + (send nil? :change $({const send} ...) (sym $_)) PATTERN # @!method expect_change_with_block(node) @@ -53,11 +53,10 @@ class ExpectChange < Base def on_send(node) return unless style == :block - expect_change_with_arguments(node) do |receiver, message| - msg = format(MSG_CALL, obj: receiver, attr: message) + msg = format(MSG_CALL, obj: receiver.source, attr: message) add_offense(node, message: msg) do |corrector| - replacement = "change { #{receiver}.#{message} }" + replacement = "change { #{receiver.source}.#{message} }" corrector.replace(node, replacement) end end diff --git a/spec/rubocop/cop/rspec/expect_change_spec.rb b/spec/rubocop/cop/rspec/expect_change_spec.rb index 82476b151..e436ea833 100644 --- a/spec/rubocop/cop/rspec/expect_change_spec.rb +++ b/spec/rubocop/cop/rspec/expect_change_spec.rb @@ -82,6 +82,21 @@ RUBY end + it 'flags change matcher with chained method call' do + expect_offense(<<-RUBY) + it do + expect { paint_users! }.to change(users.green, :count).by(1) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `change { users.green.count }`. + end + RUBY + + expect_correction(<<-RUBY) + it do + expect { paint_users! }.to change { users.green.count }.by(1) + end + RUBY + end + it 'ignores methods called change' do expect_no_offenses(<<-RUBY) it do