module RuboCop::Cop::MinitestCopRule

def define_rule(assertion_method, target_method:, preferred_method: nil, inverse: false)

Other tags:
    Api: - private

Parameters:
  • inverse (Boolean, String) -- An optional param. Order of arguments replaced by autocorrection.
  • preferred_method (Symbol) -- Is required if passing multiple target methods. Custom method name replaced by
  • target_method (Symbol, Array) -- Method name(s) offensed by assertion method arguments.
  • assertion_method (Symbol) -- Assertion method like `assert` or `refute`.

Other tags:
    Example: Multiple target methods -
def define_rule(assertion_method, target_method:, preferred_method: nil, inverse: false)
  target_methods = Array(target_method)
  if target_methods.size > 1 && preferred_method.nil?
    raise ArgumentError, '`:preferred_method` keyword argument must be used if using more than one target method.'
  end
  preferred_method = "#{assertion_method}_#{target_methods.first.to_s.delete('?')}" if preferred_method.nil?
  class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
    include ArgumentRangeHelper
    extend AutoCorrector
    MSG = 'Prefer using `#{preferred_method}(%<new_arguments>s)`.'
    RESTRICT_ON_SEND = %i[#{assertion_method}].freeze
    def on_send(node)
      return unless node.method?(:#{assertion_method})
      return unless node.arguments.first&.call_type?
      return if node.arguments.first.arguments.empty? ||
                #{target_methods}.none? { |target_method| node.arguments.first.method?(target_method) }
      add_offense(node, message: offense_message(node.arguments)) do |corrector|
        autocorrect(corrector, node, node.arguments)
      end
    end
    def autocorrect(corrector, node, arguments)
      corrector.replace(node.loc.selector, '#{preferred_method}')
      new_arguments = new_arguments(arguments).join(', ')
      corrector.replace(node.first_argument, new_arguments)
    end
    private
    def offense_message(arguments)
      message_argument = arguments.last if arguments.first != arguments.last
      new_arguments = [
        new_arguments(arguments),
        message_argument&.source
      ].flatten.compact.join(', ')
      format(
        MSG,
        new_arguments: new_arguments
      )
    end
    def new_arguments(arguments)
      receiver = correct_receiver(arguments.first.receiver)
      method_argument = arguments.first.arguments.first
      new_arguments = [receiver, method_argument&.source].compact
      inverse_condition = if %w[true false].include?('#{inverse}')
        #{inverse}
      else
        method_argument.#{inverse}
      end
      new_arguments.reverse! if inverse_condition
      new_arguments
    end
    def correct_receiver(receiver)
      receiver ? receiver.source : 'self'
    end
  RUBY
end