Vendor InverseMethods cop

This commit is contained in:
Douglas Eichelberger 2024-01-26 13:52:46 -08:00
parent 0caaa1fa36
commit ae249ec282
4 changed files with 79 additions and 5 deletions

View File

@ -64,6 +64,12 @@ Homebrew/CompactBlank:
Homebrew/MoveToExtendOS:
Enabled: false
Homebrew/NegateInclude:
Exclude:
# `exclude?` is not available here:
- "Homebrew/standalone/init.rb"
- "Homebrew/rubocops/**/*"
# `system` is a special case and aligns on second argument, so allow this for formulae.
Layout/ArgumentAlignment:
Exclude:
@ -339,13 +345,8 @@ Style/HashAsLastArrayItem:
- "**/Formula/**/*.rb"
Style/InverseMethods:
Exclude:
# Core extensions are not available here:
- "Homebrew/standalone/init.rb"
- "Homebrew/rubocops/**/*"
InverseMethods:
:blank?: :present?
:exclude?: :include?
Style/InvertibleUnlessCondition:
Enabled: true

View File

@ -7,6 +7,7 @@ require_relative "blank"
require_relative "compact_blank"
require_relative "io_read"
require_relative "move_to_extend_os"
require_relative "negate_include"
require_relative "presence"
require_relative "present"
require_relative "safe_navigation_with_blank"

View File

@ -0,0 +1,43 @@
# typed: true
# frozen_string_literal: true
module RuboCop
module Cop
module Homebrew
# Enforces the use of `collection.exclude?(obj)`
# over `!collection.include?(obj)`.
#
# @note
# This cop is unsafe because false positive will occur for
# receiver objects that do not have an `exclude?` method. (e.g. `IPAddr`)
#
# @example
# # bad
# !array.include?(2)
# !hash.include?(:key)
#
# # good
# array.exclude?(2)
# hash.exclude?(:key)
#
class NegateInclude < Base
extend AutoCorrector
MSG = "Use `.exclude?` and remove the negation part."
RESTRICT_ON_SEND = [:!].freeze
def_node_matcher :negate_include_call?, <<~PATTERN
(send (send $!nil? :include? $_) :!)
PATTERN
def on_send(node)
return unless (receiver, obj = negate_include_call?(node))
add_offense(node) do |corrector|
corrector.replace(node, "#{receiver.source}.exclude?(#{obj.source})")
end
end
end
end
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
require "rubocops/negate_include"
RSpec.describe RuboCop::Cop::Homebrew::NegateInclude, :config do
it "registers an offense and corrects when using `!include?`" do
expect_offense(<<~RUBY)
!array.include?(2)
^^^^^^^^^^^^^^^^^^ Use `.exclude?` and remove the negation part.
RUBY
expect_correction(<<~RUBY)
array.exclude?(2)
RUBY
end
it "does not register an offense when using `!include?` without receiver" do
expect_no_offenses(<<~RUBY)
!include?(2)
RUBY
end
it "does not register an offense when using `include?` or `exclude?`" do
expect_no_offenses(<<~RUBY)
array.include?(2)
array.exclude?(2)
RUBY
end
end