From 1139c2ce643300da0698ef6d6f5fb69de04a846c Mon Sep 17 00:00:00 2001 From: Benjamin Quorning Date: Tue, 9 Jun 2020 16:37:52 +0200 Subject: [PATCH] Use the new Autocorrection API The autocorrection API was changed in Rubocop v0.87.0 (pull request https://github.com/rubocop-hq/rubocop/pull/7868). Here, I change the superclass of `RuboCop::Cop::RSpec::Cop` from `::RuboCop::Cop::Cop` to `::RuboCop::Cop::Base`. This has a few consequences: - Our `#message` methods get called with a different argument than before. It *can* be customized by defining a `#callback_argument` method, but I think it is clearer to avoid callbacks altogether. - Our `#autocorrect` methods don't get called anymore. Instead, we extend `Autocorrector`, and the `corrector` is being yielded when calling `#add_offense`, so the code is mostly moved in there. For some cases, this means that some code can be removed, which is nice. For some cases, it means that the methods get too long, or the code complexity gets too high, and in those cases I chose to just call out to an `#autocorrect` method anyway, but of course passing the `corrector` and any usable local variables along. This also means we bump the dependency of RuboCop quite a bit, from '>= 0.68.1' to '>= 0.87.0'. --- .rubocop_todo.yml | 2 +- .../cop/capybara/current_path_expectation.rb | 34 ++++++++++--------- rubocop-capybara.gemspec | 2 +- tasks/cops_documentation.rake | 2 +- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d6a65b6..3846efa 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -14,4 +14,4 @@ InternalAffairs/MethodNameEqual: # Offense count: 1 # Configuration parameters: CountComments. Metrics/ClassLength: - Max: 104 + Max: 106 diff --git a/lib/rubocop/cop/capybara/current_path_expectation.rb b/lib/rubocop/cop/capybara/current_path_expectation.rb index c693031..ec51d2c 100644 --- a/lib/rubocop/cop/capybara/current_path_expectation.rb +++ b/lib/rubocop/cop/capybara/current_path_expectation.rb @@ -24,6 +24,8 @@ module Capybara # expect(page).to have_current_path(/widgets/) # class CurrentPathExpectation < Cop + extend AutoCorrector + MSG = 'Do not set an RSpec expectation on `current_path` in ' \ 'Capybara feature specs - instead, use the ' \ '`have_current_path` matcher on `page`' @@ -47,30 +49,30 @@ class CurrentPathExpectation < Cop def on_send(node) expectation_set_on_current_path(node) do - add_offense(node, location: :selector) + add_offense(node.loc.selector) do |corrector| + next unless node.chained? + + autocorrect(corrector, node) + end end end - def autocorrect(node) - lambda do |corrector| - return unless node.chained? + private - as_is_matcher(node.parent) do |to_sym, matcher_node| - rewrite_expectation(corrector, node, to_sym, matcher_node) - end + def autocorrect(corrector, node) + as_is_matcher(node.parent) do |to_sym, matcher_node| + rewrite_expectation(corrector, node, to_sym, matcher_node) + end - regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp| - rewrite_expectation(corrector, node, to_sym, matcher_node) - convert_regexp_str_to_literal(corrector, matcher_node, regexp) - end + regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp| + rewrite_expectation(corrector, node, to_sym, matcher_node) + convert_regexp_str_to_literal(corrector, matcher_node, regexp) end end - private - def rewrite_expectation(corrector, node, to_symbol, matcher_node) current_path_node = node.first_argument - corrector.replace(current_path_node.loc.expression, 'page') + corrector.replace(current_path_node, 'page') corrector.replace(node.parent.loc.selector, 'to') matcher_method = if to_symbol == :to 'have_current_path' @@ -84,7 +86,7 @@ def rewrite_expectation(corrector, node, to_symbol, matcher_node) def convert_regexp_str_to_literal(corrector, matcher_node, regexp_str) str_node = matcher_node.first_argument regexp_expr = Regexp.new(regexp_str).inspect - corrector.replace(str_node.loc.expression, regexp_expr) + corrector.replace(str_node, regexp_expr) end # `have_current_path` with no options will include the querystring @@ -97,7 +99,7 @@ def add_ignore_query_options(corrector, node) return if %i[regexp str].include?(expectation_last_child.type) corrector.insert_after( - expectation_last_child.loc.expression, + expectation_last_child, ', ignore_query: true' ) end diff --git a/rubocop-capybara.gemspec b/rubocop-capybara.gemspec index 48af29b..fb0299e 100644 --- a/rubocop-capybara.gemspec +++ b/rubocop-capybara.gemspec @@ -36,7 +36,7 @@ Gem::Specification.new do |spec| 'documentation_uri' => 'https://rubocop-rspec.readthedocs.io/' } - spec.add_runtime_dependency 'rubocop', '>= 0.68.1' + spec.add_runtime_dependency 'rubocop', '>= 0.87.0' spec.add_development_dependency 'rack' spec.add_development_dependency 'rake' diff --git a/tasks/cops_documentation.rake b/tasks/cops_documentation.rake index 8b06365..2f0ced8 100644 --- a/tasks/cops_documentation.rake +++ b/tasks/cops_documentation.rake @@ -40,7 +40,7 @@ task generate_cops_documentation: :yard_for_generate_documentation do ] config = config.for_cop(cop) safe_auto_correct = config.fetch('SafeAutoCorrect', true) - autocorrect = if cop.new.support_autocorrect? + autocorrect = if cop.support_autocorrect? "Yes #{'(Unsafe)' unless safe_auto_correct}" else 'No'