Skip to content

Commit

Permalink
Make Minitest/AssertMatch aware of assert_operator
Browse files Browse the repository at this point in the history
This PR makes `Minitest/AssertMatch` aware of `assert_operator`.
  • Loading branch information
koic committed Oct 6, 2023
1 parent 213d03c commit b94890b
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 12 deletions.
@@ -0,0 +1 @@
* [#268](https://github.com/rubocop/rubocop-minitest/pull/268): Make `Minitest/AssertMatch` aware of `assert_operator`. ([@koic][])
47 changes: 44 additions & 3 deletions lib/rubocop/cop/minitest/assert_match.rb
Expand Up @@ -11,17 +11,58 @@ module Minitest
# assert(matcher.match(string))
# assert(matcher.match?(string))
# assert(matcher =~ string)
# assert_operator(matcher, :=~, string)
# assert(matcher.match(string), 'message')
#
# # good
# assert_match(regex, string)
# assert_match(matcher, string, 'message')
#
class AssertMatch < Base
extend MinitestCopRule
include ArgumentRangeHelper
extend AutoCorrector

define_rule :assert, target_method: %i[match match? =~],
preferred_method: :assert_match, inverse: 'regexp_type?'
MSG = 'Prefer using `assert_match(%<preferred>s)`.'
RESTRICT_ON_SEND = %i[assert assert_operator].freeze

def_node_matcher :assert_match, <<~PATTERN
{
(send nil? :assert (send $_ {:match :match? :=~} $_) $...)
(send nil? :assert_operator $_ (sym :=~) $_ $...)
}
PATTERN

# rubocop:disable Metrics/AbcSize
def on_send(node)
assert_match(node) do |expected, actual, rest_args|
basic_arguments = order_expected_and_actual(expected, actual)
preferred = (message_arg = rest_args.first) ? "#{basic_arguments}, #{message_arg.source}" : basic_arguments
message = format(MSG, preferred: preferred)

add_offense(node, message: message) do |corrector|
corrector.replace(node.loc.selector, 'assert_match')

range = if node.method?(:assert)
node.first_argument
else
node.first_argument.source_range.begin.join(node.arguments[2].source_range.end)
end

corrector.replace(range, basic_arguments)
end
end
end
# rubocop:enable Metrics/AbcSize

private

def order_expected_and_actual(expected, actual)
if actual.regexp_type?
[actual, expected]
else
[expected, actual]
end.map(&:source).join(', ')
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/minitest/refute_match.rb
Expand Up @@ -11,6 +11,7 @@ module Minitest
# refute(matcher.match(string))
# refute(matcher.match?(string))
# refute(matcher =~ string)
# refute_operator(matcher, :=~, string)
# refute(matcher.match(string), 'message')
#
# # good
Expand Down
39 changes: 30 additions & 9 deletions test/rubocop/cop/minitest/assert_match_test.rb
Expand Up @@ -105,24 +105,35 @@ def test_do_something
RUBY
end

# Redundant parentheses should be removed by `Style/RedundantParentheses` cop.
define_method("test_registers_offense_when_using_assert_with_#{matcher}_in_redundant_parentheses") do
assert_offense(<<~RUBY, matcher: matcher)
assert_no_offenses(<<~RUBY, matcher: matcher)
class FooTest < Minitest::Test
def test_do_something
assert((matcher.#{matcher}(string)))
^^^^^^^^^^^^^^^^^{matcher}^^^^^^^^^^ Prefer using `assert_match(matcher, string)`.
end
end
RUBY
end
end

assert_correction(<<~RUBY)
class FooTest < Minitest::Test
def test_do_something
assert_match((matcher, string))
end
def test_registers_offense_when_using_assert_operator_with_match_operator
assert_offense(<<~RUBY)
class FooTest < Minitest::Test
def test_do_something
assert_operator(matcher, :=~, object)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer using `assert_match(matcher, object)`.
end
RUBY
end
end
RUBY

assert_correction(<<~RUBY)
class FooTest < Minitest::Test
def test_do_something
assert_match(matcher, object)
end
end
RUBY
end

def test_does_not_register_offense_when_using_assert_match
Expand Down Expand Up @@ -154,4 +165,14 @@ def test_do_something
end
RUBY
end

def test_does_not_register_offense_when_using_assert_operator_with_mismatch_operator
assert_no_offenses(<<~RUBY)
class FooTest < Minitest::Test
def test_do_something
assert_operator(matcher, :!~, object)
end
end
RUBY
end
end

0 comments on commit b94890b

Please sign in to comment.