diff options
author | Daniel Colson <danieljamescolson@gmail.com> | 2018-04-17 08:37:35 -0400 |
---|---|---|
committer | Daniel Colson <danieljamescolson@gmail.com> | 2018-04-19 08:11:28 -0400 |
commit | 087e0ccb72e7a1491701dd1d1d49746f745d9d68 (patch) | |
tree | da79375760e74db0bc466695cce13689666ef430 /ci | |
parent | ef2af628a9ec1cc4e7b6997a021dd3f85cfe4665 (diff) | |
download | rails-087e0ccb72e7a1491701dd1d1d49746f745d9d68.tar.gz rails-087e0ccb72e7a1491701dd1d1d49746f745d9d68.tar.bz2 rails-087e0ccb72e7a1491701dd1d1d49746f745d9d68.zip |
Add RuboCop for `assert_not` over `assert !`
We added `assert_not` in f75addd "to replace warty 'assert !foo'".
fa8d35b agrees that it is warty, and so do I. This custom Rubocop rule
turns the wart into a violation.
As with my last custom cop, https://github.com/rails/rails/pull/32441,
I want to make sure this looks right on code climate before pushing
another commit to autocorrect everything.
@toshimaru I just noticed
https://github.com/toshimaru/rubocop-rails/pull/26
Is there a better way to add these custom cops, or were you saying we
shouldn't have custom cops at all?
Diffstat (limited to 'ci')
-rw-r--r-- | ci/custom_cops/lib/custom_cops.rb | 1 | ||||
-rw-r--r-- | ci/custom_cops/lib/custom_cops/assert_not.rb | 40 | ||||
-rw-r--r-- | ci/custom_cops/test/custom_cops/assert_not_test.rb | 42 | ||||
-rw-r--r-- | ci/custom_cops/test/custom_cops/refute_not_test.rb | 11 | ||||
-rw-r--r-- | ci/custom_cops/test/support/cop_helper.rb | 12 |
5 files changed, 96 insertions, 10 deletions
diff --git a/ci/custom_cops/lib/custom_cops.rb b/ci/custom_cops/lib/custom_cops.rb index d5d17f8856..157b8247e4 100644 --- a/ci/custom_cops/lib/custom_cops.rb +++ b/ci/custom_cops/lib/custom_cops.rb @@ -1,3 +1,4 @@ # frozen_string_literal: true require_relative "custom_cops/refute_not" +require_relative "custom_cops/assert_not" diff --git a/ci/custom_cops/lib/custom_cops/assert_not.rb b/ci/custom_cops/lib/custom_cops/assert_not.rb new file mode 100644 index 0000000000..e722448e21 --- /dev/null +++ b/ci/custom_cops/lib/custom_cops/assert_not.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module CustomCops + # Enforces the use of `assert_not` over `assert !`. + # + # @example + # # bad + # assert !x + # assert ! x + # + # # good + # assert_not x + # + class AssertNot < RuboCop::Cop::Cop + MSG = "Prefer `assert_not` over `assert !`" + + def_node_matcher :offensive?, "(send nil? :assert (send ... :!))" + + def on_send(node) + add_offense(node) if offensive?(node) + end + + def autocorrect(node) + expression = node.loc.expression + + ->(corrector) do + corrector.replace( + expression, + corrected_source(expression.source) + ) + end + end + + private + + def corrected_source(source) + source.gsub(/^assert(\(| ) *! */, "assert_not\\1") + end + end +end diff --git a/ci/custom_cops/test/custom_cops/assert_not_test.rb b/ci/custom_cops/test/custom_cops/assert_not_test.rb new file mode 100644 index 0000000000..abb151aeb4 --- /dev/null +++ b/ci/custom_cops/test/custom_cops/assert_not_test.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require "support/cop_helper" +require_relative "../../lib/custom_cops/assert_not" + +class AssertNotTest < ActiveSupport::TestCase + include CopHelper + + setup do + @cop = CustomCops::AssertNot.new + end + + test "rejects 'assert !'" do + inspect_source @cop, "assert !x" + assert_offense @cop, "^^^^^^^^^ Prefer `assert_not` over `assert !`" + end + + test "rejects 'assert !' with a complex value" do + inspect_source @cop, "assert !a.b(c)" + assert_offense @cop, "^^^^^^^^^^^^^^ Prefer `assert_not` over `assert !`" + end + + test "autocorrects `assert !`" do + corrected = autocorrect_source(@cop, "assert !false") + assert_equal "assert_not false", corrected + end + + test "autocorrects `assert !` with extra spaces" do + corrected = autocorrect_source(@cop, "assert ! false") + assert_equal "assert_not false", corrected + end + + test "autocorrects `assert !` with parentheses" do + corrected = autocorrect_source(@cop, "assert(!false)") + assert_equal "assert_not(false)", corrected + end + + test "accepts `assert_not`" do + inspect_source @cop, "assert_not x" + assert_empty @cop.offenses + end +end diff --git a/ci/custom_cops/test/custom_cops/refute_not_test.rb b/ci/custom_cops/test/custom_cops/refute_not_test.rb index 5dbd8bf32a..f0f6eaeda0 100644 --- a/ci/custom_cops/test/custom_cops/refute_not_test.rb +++ b/ci/custom_cops/test/custom_cops/refute_not_test.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "support/cop_helper" -require "./lib/custom_cops/refute_not" +require_relative "../../lib/custom_cops/refute_not" class RefuteNotTest < ActiveSupport::TestCase include CopHelper @@ -59,15 +59,6 @@ class RefuteNotTest < ActiveSupport::TestCase private - def assert_offense(cop, expected_message) - assert_not_empty cop.offenses - - offense = cop.offenses.first - carets = "^" * offense.column_length - - assert_equal expected_message, "#{carets} #{offense.message}" - end - def offense_message(refute_method, assert_method) carets = "^" * refute_method.to_s.length "#{carets} Prefer `#{assert_method}` over `#{refute_method}`" diff --git a/ci/custom_cops/test/support/cop_helper.rb b/ci/custom_cops/test/support/cop_helper.rb index d259154df5..c2c6b969dd 100644 --- a/ci/custom_cops/test/support/cop_helper.rb +++ b/ci/custom_cops/test/support/cop_helper.rb @@ -16,6 +16,18 @@ module CopHelper rewrite(cop, processed_source) end + def assert_offense(cop, expected_message) + assert_not_empty( + cop.offenses, + "Expected offense with message \"#{expected_message}\", but got no offense" + ) + + offense = cop.offenses.first + carets = "^" * offense.column_length + + assert_equal expected_message, "#{carets} #{offense.message}" + end + private TARGET_RUBY_VERSION = 2.4 |