aboutsummaryrefslogtreecommitdiffstats
path: root/ci/custom_cops/lib
diff options
context:
space:
mode:
Diffstat (limited to 'ci/custom_cops/lib')
-rw-r--r--ci/custom_cops/lib/custom_cops.rb1
-rw-r--r--ci/custom_cops/lib/custom_cops/assert_not.rb40
2 files changed, 41 insertions, 0 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