diff --git a/lib/rubocop/cop/minitest/assert_empty.rb b/lib/rubocop/cop/minitest/assert_empty.rb index d049f8d2..f9d40d13 100644 --- a/lib/rubocop/cop/minitest/assert_empty.rb +++ b/lib/rubocop/cop/minitest/assert_empty.rb @@ -15,7 +15,7 @@ module Minitest # assert_empty(object) # assert_empty(object, 'message') # - class AssertEmpty < Cop + class AssertEmpty < Base extend MinitestCopRule define_rule :assert, target_method: :empty? diff --git a/lib/rubocop/cop/minitest/assert_empty_literal.rb b/lib/rubocop/cop/minitest/assert_empty_literal.rb index f8915f6c..84f6616c 100644 --- a/lib/rubocop/cop/minitest/assert_empty_literal.rb +++ b/lib/rubocop/cop/minitest/assert_empty_literal.rb @@ -14,8 +14,9 @@ module Minitest # # good # assert_empty(object) # - class AssertEmptyLiteral < Cop + class AssertEmptyLiteral < Base include ArgumentRangeHelper + extend AutoCorrector MSG = 'Prefer using `assert_empty(%s)` over ' \ '`assert_equal(%s, %s)`.' @@ -32,15 +33,9 @@ def on_send(node) args = matchers.map(&:source).join(', ') message = format(MSG, literal: literal.source, arguments: args) - add_offense(node, message: message) - end - end - - def autocorrect(node) - assert_equal_with_empty_literal(node) do |_literal, matchers| - object = matchers.first + add_offense(node, message: message) do |corrector| + object = matchers.first - lambda do |corrector| corrector.replace(node.loc.selector, 'assert_empty') corrector.replace(first_and_second_arguments_range(node), object.source) end diff --git a/lib/rubocop/cop/minitest/assert_equal.rb b/lib/rubocop/cop/minitest/assert_equal.rb index 8946b5c4..949b9136 100644 --- a/lib/rubocop/cop/minitest/assert_equal.rb +++ b/lib/rubocop/cop/minitest/assert_equal.rb @@ -13,7 +13,7 @@ module Minitest # # good # assert_equal("rubocop-minitest", actual) # - class AssertEqual < Cop + class AssertEqual < Base extend MinitestCopRule define_rule :assert, target_method: :==, preferred_method: :assert_equal diff --git a/lib/rubocop/cop/minitest/assert_in_delta.rb b/lib/rubocop/cop/minitest/assert_in_delta.rb index 235c826a..565846b8 100644 --- a/lib/rubocop/cop/minitest/assert_in_delta.rb +++ b/lib/rubocop/cop/minitest/assert_in_delta.rb @@ -15,8 +15,9 @@ module Minitest # assert_in_delta(0.2, actual) # assert_in_delta(0.2, actual, 0.001, 'message') # - class AssertInDelta < Cop + class AssertInDelta < Base include InDeltaMixin + extend AutoCorrector RESTRICT_ON_SEND = %i[assert_equal].freeze diff --git a/lib/rubocop/cop/minitest/assert_includes.rb b/lib/rubocop/cop/minitest/assert_includes.rb index d4c814a3..7efac31b 100644 --- a/lib/rubocop/cop/minitest/assert_includes.rb +++ b/lib/rubocop/cop/minitest/assert_includes.rb @@ -15,7 +15,7 @@ module Minitest # assert_includes(collection, object) # assert_includes(collection, object, 'message') # - class AssertIncludes < Cop + class AssertIncludes < Base extend MinitestCopRule define_rule :assert, target_method: :include?, preferred_method: :assert_includes diff --git a/lib/rubocop/cop/minitest/assert_instance_of.rb b/lib/rubocop/cop/minitest/assert_instance_of.rb index f36f7e26..495a8031 100644 --- a/lib/rubocop/cop/minitest/assert_instance_of.rb +++ b/lib/rubocop/cop/minitest/assert_instance_of.rb @@ -15,7 +15,7 @@ module Minitest # assert_instance_of(Class, object) # assert_instance_of(Class, object, 'message') # - class AssertInstanceOf < Cop + class AssertInstanceOf < Base extend MinitestCopRule define_rule :assert, target_method: :instance_of?, inverse: true diff --git a/lib/rubocop/cop/minitest/assert_kind_of.rb b/lib/rubocop/cop/minitest/assert_kind_of.rb index d667ea87..f56d9291 100644 --- a/lib/rubocop/cop/minitest/assert_kind_of.rb +++ b/lib/rubocop/cop/minitest/assert_kind_of.rb @@ -15,7 +15,7 @@ module Minitest # assert_kind_of(Class, object) # assert_kind_of(Class, object, 'message') # - class AssertKindOf < Cop + class AssertKindOf < Base extend MinitestCopRule define_rule :assert, target_method: :kind_of?, inverse: true diff --git a/lib/rubocop/cop/minitest/assert_match.rb b/lib/rubocop/cop/minitest/assert_match.rb index c37e7d6f..de10ce5b 100644 --- a/lib/rubocop/cop/minitest/assert_match.rb +++ b/lib/rubocop/cop/minitest/assert_match.rb @@ -15,7 +15,7 @@ module Minitest # assert_match(regex, string) # assert_match(matcher, string, 'message') # - class AssertMatch < Cop + class AssertMatch < Base extend MinitestCopRule define_rule :assert, target_method: :match diff --git a/lib/rubocop/cop/minitest/assert_nil.rb b/lib/rubocop/cop/minitest/assert_nil.rb index 52be7171..88e58470 100644 --- a/lib/rubocop/cop/minitest/assert_nil.rb +++ b/lib/rubocop/cop/minitest/assert_nil.rb @@ -15,8 +15,9 @@ module Minitest # assert_nil(actual) # assert_nil(actual, 'message') # - class AssertNil < Cop + class AssertNil < Base include ArgumentRangeHelper + extend AutoCorrector MSG = 'Prefer using `assert_nil(%s)` over ' \ '`assert_equal(nil, %s)`.' @@ -32,17 +33,9 @@ def on_send(node) arguments = [actual.source, message&.source].compact.join(', ') - add_offense(node, message: format(MSG, arguments: arguments)) - end - end - - def autocorrect(node) - lambda do |corrector| - assert_equal_with_nil(node) do |actual| + add_offense(node, message: format(MSG, arguments: arguments)) do |corrector| corrector.replace(node.loc.selector, 'assert_nil') - corrector.replace( - first_and_second_arguments_range(node), actual.source - ) + corrector.replace(first_and_second_arguments_range(node), actual.source) end end end diff --git a/lib/rubocop/cop/minitest/assert_output.rb b/lib/rubocop/cop/minitest/assert_output.rb index 86bc933f..15e26877 100644 --- a/lib/rubocop/cop/minitest/assert_output.rb +++ b/lib/rubocop/cop/minitest/assert_output.rb @@ -15,7 +15,7 @@ module Minitest # # good # assert_output(expected) { puts object.method } # - class AssertOutput < Cop + class AssertOutput < Base include MinitestExplorationHelpers MSG = 'Use `assert_output` instead of mutating %s.' diff --git a/lib/rubocop/cop/minitest/assert_path_exists.rb b/lib/rubocop/cop/minitest/assert_path_exists.rb index eab82f69..5b6da709 100644 --- a/lib/rubocop/cop/minitest/assert_path_exists.rb +++ b/lib/rubocop/cop/minitest/assert_path_exists.rb @@ -15,7 +15,9 @@ module Minitest # assert_path_exists(path) # assert_path_exists(path, 'message') # - class AssertPathExists < Cop + class AssertPathExists < Base + extend AutoCorrector + MSG = 'Prefer using `%s` over `%s`.' RESTRICT_ON_SEND = %i[assert].freeze @@ -32,17 +34,8 @@ def on_send(node) good_method = build_good_method(path, failure_message) message = format(MSG, good_method: good_method, bad_method: node.source) - add_offense(node, message: message) - end - end - - def autocorrect(node) - assert_file_exists(node) do |path, failure_message| - failure_message = failure_message.first - - lambda do |corrector| - replacement = build_good_method(path, failure_message) - corrector.replace(node, replacement) + add_offense(node, message: message) do |corrector| + corrector.replace(node, good_method) end end end diff --git a/lib/rubocop/cop/minitest/assert_respond_to.rb b/lib/rubocop/cop/minitest/assert_respond_to.rb index 4b6d6cd0..c1f33b88 100644 --- a/lib/rubocop/cop/minitest/assert_respond_to.rb +++ b/lib/rubocop/cop/minitest/assert_respond_to.rb @@ -17,7 +17,7 @@ module Minitest # assert_respond_to(object, :do_something, 'message') # assert_respond_to(self, :do_something) # - class AssertRespondTo < Cop + class AssertRespondTo < Base extend MinitestCopRule define_rule :assert, target_method: :respond_to? diff --git a/lib/rubocop/cop/minitest/assert_silent.rb b/lib/rubocop/cop/minitest/assert_silent.rb index 9eb10f0d..e4e09245 100644 --- a/lib/rubocop/cop/minitest/assert_silent.rb +++ b/lib/rubocop/cop/minitest/assert_silent.rb @@ -13,7 +13,9 @@ module Minitest # # good # assert_silent { puts object.do_something } # - class AssertSilent < Cop + class AssertSilent < Base + extend AutoCorrector + MSG = 'Prefer using `assert_silent` over `assert_output("", "")`.' def_node_matcher :assert_silent_candidate?, <<~PATTERN @@ -25,12 +27,12 @@ class AssertSilent < Cop PATTERN def on_block(node) - add_offense(node.send_node) if assert_silent_candidate?(node) - end + return unless assert_silent_candidate?(node) + + send_node = node.send_node - def autocorrect(node) - lambda do |corrector| - corrector.replace(node, 'assert_silent') + add_offense(send_node) do |corrector| + corrector.replace(send_node, 'assert_silent') end end diff --git a/lib/rubocop/cop/minitest/assert_truthy.rb b/lib/rubocop/cop/minitest/assert_truthy.rb index 3268f64f..83accfd7 100644 --- a/lib/rubocop/cop/minitest/assert_truthy.rb +++ b/lib/rubocop/cop/minitest/assert_truthy.rb @@ -15,8 +15,9 @@ module Minitest # assert(actual) # assert(actual, 'message') # - class AssertTruthy < Cop + class AssertTruthy < Base include ArgumentRangeHelper + extend AutoCorrector MSG = 'Prefer using `assert(%s)` over ' \ '`assert_equal(true, %s)`.' @@ -32,17 +33,9 @@ def on_send(node) arguments = [actual.source, message&.source].compact.join(', ') - add_offense(node, message: format(MSG, arguments: arguments)) - end - end - - def autocorrect(node) - lambda do |corrector| - assert_equal_with_truthy(node) do |actual| + add_offense(node, message: format(MSG, arguments: arguments)) do |corrector| corrector.replace(node.loc.selector, 'assert') - corrector.replace( - first_and_second_arguments_range(node), actual.source - ) + corrector.replace(first_and_second_arguments_range(node), actual.source) end end end diff --git a/lib/rubocop/cop/minitest/assert_with_expected_argument.rb b/lib/rubocop/cop/minitest/assert_with_expected_argument.rb index ec5ae247..ff45a2ae 100644 --- a/lib/rubocop/cop/minitest/assert_with_expected_argument.rb +++ b/lib/rubocop/cop/minitest/assert_with_expected_argument.rb @@ -19,7 +19,7 @@ module Minitest # assert_equal(expected, actual) # assert(foo, 'message') # - class AssertWithExpectedArgument < Cop + class AssertWithExpectedArgument < Base MSG = 'Did you mean to use `assert_equal(%s)`?' RESTRICT_ON_SEND = %i[assert].freeze diff --git a/lib/rubocop/cop/minitest/assertion_in_lifecycle_hook.rb b/lib/rubocop/cop/minitest/assertion_in_lifecycle_hook.rb index 6a0860b2..4824d84f 100644 --- a/lib/rubocop/cop/minitest/assertion_in_lifecycle_hook.rb +++ b/lib/rubocop/cop/minitest/assertion_in_lifecycle_hook.rb @@ -20,7 +20,7 @@ module Minitest # end # end # - class AssertionInLifecycleHook < Cop + class AssertionInLifecycleHook < Base include MinitestExplorationHelpers MSG = 'Do not use `%s` in `%s` hook.' diff --git a/lib/rubocop/cop/minitest/global_expectations.rb b/lib/rubocop/cop/minitest/global_expectations.rb index ba860170..7edfc8df 100644 --- a/lib/rubocop/cop/minitest/global_expectations.rb +++ b/lib/rubocop/cop/minitest/global_expectations.rb @@ -16,7 +16,9 @@ module Minitest # _(musts).must_equal expected_musts # _(wonts).wont_match expected_wonts # _ { musts }.must_raise TypeError - class GlobalExpectations < Cop + class GlobalExpectations < Base + extend AutoCorrector + MSG = 'Use `%s` instead.' VALUE_MATCHERS = %i[ @@ -64,13 +66,8 @@ def on_send(node) return unless value_global_expectation?(node) || block_global_expectation?(node) message = format(MSG, preferred: preferred_receiver(node)) - add_offense(node, location: node.receiver.source_range, message: message) - end - - def autocorrect(node) - return unless value_global_expectation?(node) || block_global_expectation?(node) - lambda do |corrector| + add_offense(node.receiver.source_range, message: message) do |corrector| receiver = node.receiver.source_range if BLOCK_MATCHERS.include?(node.method_name) diff --git a/lib/rubocop/cop/minitest/literal_as_actual_argument.rb b/lib/rubocop/cop/minitest/literal_as_actual_argument.rb index 21069fe9..505449fd 100644 --- a/lib/rubocop/cop/minitest/literal_as_actual_argument.rb +++ b/lib/rubocop/cop/minitest/literal_as_actual_argument.rb @@ -17,8 +17,9 @@ module Minitest # assert_equal [1, 2], foo # assert_equal [1, 2], foo, 'message' # - class LiteralAsActualArgument < Cop + class LiteralAsActualArgument < Base include ArgumentRangeHelper + extend AutoCorrector MSG = 'Replace the literal with the first argument.' RESTRICT_ON_SEND = %i[assert_equal].freeze @@ -27,25 +28,24 @@ def on_send(node) return unless node.method?(:assert_equal) actual = node.arguments[1] - return unless actual + return unless actual&.recursive_basic_literal? - add_offense(node, location: all_arguments_range(node)) if actual.recursive_basic_literal? + add_offense(all_arguments_range(node)) do |corrector| + autocorrect(corrector, node) + end end - def autocorrect(node) + def autocorrect(corrector, node) expected, actual, message = *node.arguments - lambda do |corrector| - new_actual_source = - if actual.hash_type? && !actual.braces? - "{#{actual.source}}" - else - actual.source - end - arguments = [new_actual_source, expected.source, message&.source].compact.join(', ') + new_actual_source = if actual.hash_type? && !actual.braces? + "{#{actual.source}}" + else + actual.source + end + arguments = [new_actual_source, expected.source, message&.source].compact.join(', ') - corrector.replace(node, "assert_equal(#{arguments})") - end + corrector.replace(node, "assert_equal(#{arguments})") end end end diff --git a/lib/rubocop/cop/minitest/multiple_assertions.rb b/lib/rubocop/cop/minitest/multiple_assertions.rb index 14500eff..a24f5886 100644 --- a/lib/rubocop/cop/minitest/multiple_assertions.rb +++ b/lib/rubocop/cop/minitest/multiple_assertions.rb @@ -26,7 +26,7 @@ module Minitest # end # end # - class MultipleAssertions < Cop + class MultipleAssertions < Base include ConfigurableMax include MinitestExplorationHelpers @@ -43,7 +43,7 @@ def on_class(class_node) self.max = assertions_count message = format(MSG, total: assertions_count, max: max_assertions) - add_offense(node, location: :name, message: message) + add_offense(node.loc.name, message: message) end end diff --git a/lib/rubocop/cop/minitest/refute_empty.rb b/lib/rubocop/cop/minitest/refute_empty.rb index 52d4704b..d27b26dc 100644 --- a/lib/rubocop/cop/minitest/refute_empty.rb +++ b/lib/rubocop/cop/minitest/refute_empty.rb @@ -15,7 +15,7 @@ module Minitest # refute_empty(object) # refute_empty(object, 'message') # - class RefuteEmpty < Cop + class RefuteEmpty < Base extend MinitestCopRule define_rule :refute, target_method: :empty? diff --git a/lib/rubocop/cop/minitest/refute_equal.rb b/lib/rubocop/cop/minitest/refute_equal.rb index 32ac3619..a7d084a2 100644 --- a/lib/rubocop/cop/minitest/refute_equal.rb +++ b/lib/rubocop/cop/minitest/refute_equal.rb @@ -14,8 +14,9 @@ module Minitest # # good # refute_equal("rubocop-minitest", actual) # - class RefuteEqual < Cop + class RefuteEqual < Base include ArgumentRangeHelper + extend AutoCorrector MSG = 'Prefer using `refute_equal(%s)` over ' \ '`assert(%s)`.' @@ -29,13 +30,10 @@ def on_send(node) preferred, over = process_not_equal(node) return unless preferred && over - message = format(MSG, preferred: preferred, over: over) - add_offense(node, message: message) - end + assert_not_equal(node) do |_, expected, actual| + message = format(MSG, preferred: preferred, over: over) - def autocorrect(node) - lambda do |corrector| - assert_not_equal(node) do |_, expected, actual| + add_offense(node, message: message) do |corrector| corrector.replace(node.loc.selector, 'refute_equal') replacement = [expected, actual].map(&:source).join(', ') diff --git a/lib/rubocop/cop/minitest/refute_false.rb b/lib/rubocop/cop/minitest/refute_false.rb index 9ae71f0b..1e9244f6 100644 --- a/lib/rubocop/cop/minitest/refute_false.rb +++ b/lib/rubocop/cop/minitest/refute_false.rb @@ -18,8 +18,9 @@ module Minitest # refute(actual) # refute(actual, 'message') # - class RefuteFalse < Cop + class RefuteFalse < Base include ArgumentRangeHelper + extend AutoCorrector MSG_FOR_ASSERT_EQUAL = 'Prefer using `refute(%s)` over ' \ '`assert_equal(false, %s)`.' @@ -36,38 +37,29 @@ class RefuteFalse < Cop PATTERN def on_send(node) - actual, rest_receiver_arg = assert_equal_with_false(node) || - assert_with_bang_argument(node) + actual, rest_receiver_arg = assert_equal_with_false(node) || assert_with_bang_argument(node) return unless actual message_argument = rest_receiver_arg.first arguments = [actual.source, message_argument&.source].compact.join(', ') - message = if node.method?(:assert_equal) - MSG_FOR_ASSERT_EQUAL - else - MSG_FOR_ASSERT - end + message = node.method?(:assert_equal) ? MSG_FOR_ASSERT_EQUAL : MSG_FOR_ASSERT - add_offense(node, message: format(message, arguments: arguments)) + add_offense(node, message: format(message, arguments: arguments)) do |corrector| + autocorrect(corrector, node, actual) + end end - def autocorrect(node) - lambda do |corrector| - corrector.replace(node.loc.selector, 'refute') + private - assert_equal_with_false(node) do |actual| - corrector.replace( - first_and_second_arguments_range(node), actual.source - ) - end + def autocorrect(corrector, node, actual) + corrector.replace(node.loc.selector, 'refute') - assert_with_bang_argument(node) do |actual| - corrector.replace( - first_argument_range(node), actual.source - ) - end + if node.method?(:assert_equal) + corrector.replace(first_and_second_arguments_range(node), actual.source) + else + corrector.replace(first_argument_range(node), actual.source) end end end diff --git a/lib/rubocop/cop/minitest/refute_in_delta.rb b/lib/rubocop/cop/minitest/refute_in_delta.rb index 043d74c9..203e6d32 100644 --- a/lib/rubocop/cop/minitest/refute_in_delta.rb +++ b/lib/rubocop/cop/minitest/refute_in_delta.rb @@ -15,8 +15,9 @@ module Minitest # refute_in_delta(0.2, actual) # refute_in_delta(0.2, actual, 0.001, 'message') # - class RefuteInDelta < Cop + class RefuteInDelta < Base include InDeltaMixin + extend AutoCorrector RESTRICT_ON_SEND = %i[refute_equal].freeze diff --git a/lib/rubocop/cop/minitest/refute_includes.rb b/lib/rubocop/cop/minitest/refute_includes.rb index e19433c4..6ef4101f 100644 --- a/lib/rubocop/cop/minitest/refute_includes.rb +++ b/lib/rubocop/cop/minitest/refute_includes.rb @@ -15,7 +15,7 @@ module Minitest # refute_includes(collection, object) # refute_includes(collection, object, 'message') # - class RefuteIncludes < Cop + class RefuteIncludes < Base extend MinitestCopRule define_rule :refute, target_method: :include?, preferred_method: :refute_includes diff --git a/lib/rubocop/cop/minitest/refute_instance_of.rb b/lib/rubocop/cop/minitest/refute_instance_of.rb index de70a2c6..20fba5c9 100644 --- a/lib/rubocop/cop/minitest/refute_instance_of.rb +++ b/lib/rubocop/cop/minitest/refute_instance_of.rb @@ -15,7 +15,7 @@ module Minitest # refute_instance_of(Class, object) # refute_instance_of(Class, object, 'message') # - class RefuteInstanceOf < Cop + class RefuteInstanceOf < Base extend MinitestCopRule define_rule :refute, target_method: :instance_of?, inverse: true diff --git a/lib/rubocop/cop/minitest/refute_kind_of.rb b/lib/rubocop/cop/minitest/refute_kind_of.rb index 772775ba..86165099 100644 --- a/lib/rubocop/cop/minitest/refute_kind_of.rb +++ b/lib/rubocop/cop/minitest/refute_kind_of.rb @@ -15,7 +15,7 @@ module Minitest # refute_kind_of(Class, object) # refute_kind_of(Class, object, 'message') # - class RefuteKindOf < Cop + class RefuteKindOf < Base extend MinitestCopRule define_rule :refute, target_method: :kind_of?, inverse: true diff --git a/lib/rubocop/cop/minitest/refute_match.rb b/lib/rubocop/cop/minitest/refute_match.rb index 41983f1d..feba268a 100644 --- a/lib/rubocop/cop/minitest/refute_match.rb +++ b/lib/rubocop/cop/minitest/refute_match.rb @@ -15,7 +15,7 @@ module Minitest # refute_match(matcher, string) # refute_match(matcher, string, 'message') # - class RefuteMatch < Cop + class RefuteMatch < Base extend MinitestCopRule define_rule :refute, target_method: :match diff --git a/lib/rubocop/cop/minitest/refute_nil.rb b/lib/rubocop/cop/minitest/refute_nil.rb index ae46dc2c..d33f6bf8 100644 --- a/lib/rubocop/cop/minitest/refute_nil.rb +++ b/lib/rubocop/cop/minitest/refute_nil.rb @@ -15,8 +15,9 @@ module Minitest # refute_nil(actual) # refute_nil(actual, 'message') # - class RefuteNil < Cop + class RefuteNil < Base include ArgumentRangeHelper + extend AutoCorrector MSG = 'Prefer using `refute_nil(%s)` over ' \ '`refute_equal(nil, %s)`.' @@ -32,13 +33,7 @@ def on_send(node) arguments = [actual.source, message&.source].compact.join(', ') - add_offense(node, message: format(MSG, arguments: arguments)) - end - end - - def autocorrect(node) - lambda do |corrector| - refute_equal_with_nil(node) do |actual| + add_offense(node, message: format(MSG, arguments: arguments)) do |corrector| corrector.replace(node.loc.selector, 'refute_nil') corrector.replace( first_and_second_arguments_range(node), actual.source diff --git a/lib/rubocop/cop/minitest/refute_path_exists.rb b/lib/rubocop/cop/minitest/refute_path_exists.rb index a1c47fa2..5cea82b2 100644 --- a/lib/rubocop/cop/minitest/refute_path_exists.rb +++ b/lib/rubocop/cop/minitest/refute_path_exists.rb @@ -15,7 +15,9 @@ module Minitest # refute_path_exists(path) # refute_path_exists(path, 'message') # - class RefutePathExists < Cop + class RefutePathExists < Base + extend AutoCorrector + MSG = 'Prefer using `%s` over `%s`.' RESTRICT_ON_SEND = %i[refute].freeze @@ -32,17 +34,8 @@ def on_send(node) good_method = build_good_method(path, failure_message) message = format(MSG, good_method: good_method, bad_method: node.source) - add_offense(node, message: message) - end - end - - def autocorrect(node) - refute_file_exists(node) do |path, failure_message| - failure_message = failure_message.first - - lambda do |corrector| - replacement = build_good_method(path, failure_message) - corrector.replace(node, replacement) + add_offense(node, message: message) do |corrector| + corrector.replace(node, good_method) end end end diff --git a/lib/rubocop/cop/minitest/refute_respond_to.rb b/lib/rubocop/cop/minitest/refute_respond_to.rb index 1d16f165..0aea6c7c 100644 --- a/lib/rubocop/cop/minitest/refute_respond_to.rb +++ b/lib/rubocop/cop/minitest/refute_respond_to.rb @@ -17,7 +17,7 @@ module Minitest # refute_respond_to(object, :do_something, 'message') # refute_respond_to(self, :do_something) # - class RefuteRespondTo < Cop + class RefuteRespondTo < Base extend MinitestCopRule define_rule :refute, target_method: :respond_to? diff --git a/lib/rubocop/cop/minitest/test_method_name.rb b/lib/rubocop/cop/minitest/test_method_name.rb index 671aa439..c62c60ac 100644 --- a/lib/rubocop/cop/minitest/test_method_name.rb +++ b/lib/rubocop/cop/minitest/test_method_name.rb @@ -27,9 +27,10 @@ module Minitest # end # end # - class TestMethodName < Cop + class TestMethodName < Base include MinitestExplorationHelpers include DefNode + extend AutoCorrector MSG = 'Test method name should start with `test_` prefix.' @@ -37,13 +38,13 @@ def on_class(class_node) return unless test_class?(class_node) class_elements(class_node).each do |node| - add_offense(node, location: :name) if offense?(node) - end - end + next unless offense?(node) + + test_method_name = node.loc.name - def autocorrect(node) - lambda do |corrector| - corrector.replace(node.loc.name, "test_#{node.method_name}") + add_offense(test_method_name) do |corrector| + corrector.replace(test_method_name, "test_#{node.method_name}") + end end end diff --git a/lib/rubocop/cop/minitest/unspecified_exception.rb b/lib/rubocop/cop/minitest/unspecified_exception.rb index fafa48ed..ef5482a7 100644 --- a/lib/rubocop/cop/minitest/unspecified_exception.rb +++ b/lib/rubocop/cop/minitest/unspecified_exception.rb @@ -14,7 +14,7 @@ module Minitest # assert_raises(FooException) { raise FooException } # assert_raises(FooException, 'This should have raised') { raise FooException } # - class UnspecifiedException < Cop + class UnspecifiedException < Base MSG = 'Specify the exception being captured.' def on_block(block_node) diff --git a/lib/rubocop/cop/mixin/in_delta_mixin.rb b/lib/rubocop/cop/mixin/in_delta_mixin.rb index 44c87d5b..034f0a58 100644 --- a/lib/rubocop/cop/mixin/in_delta_mixin.rb +++ b/lib/rubocop/cop/mixin/in_delta_mixin.rb @@ -9,24 +9,14 @@ module InDeltaMixin def on_send(node) equal_floats_call(node) do |expected, actual, message| message = message.first + good_method = build_good_method(expected, actual, message) if expected.float_type? || actual.float_type? - message = format(MSG, - good_method: build_good_method(expected, actual, message), - bad_method: node.source) + message = format(MSG, good_method: good_method, bad_method: node.source) - add_offense(node, message: message) - end - end - end - - def autocorrect(node) - equal_floats_call(node) do |expected, actual, message| - message = message.first - replacement = build_good_method(expected, actual, message) - - lambda do |corrector| - corrector.replace(node, replacement) + add_offense(node, message: message) do |corrector| + corrector.replace(node, good_method) + end end end end diff --git a/lib/rubocop/cop/mixin/minitest_cop_rule.rb b/lib/rubocop/cop/mixin/minitest_cop_rule.rb index 87750fc8..641e33f0 100644 --- a/lib/rubocop/cop/mixin/minitest_cop_rule.rb +++ b/lib/rubocop/cop/mixin/minitest_cop_rule.rb @@ -26,6 +26,7 @@ def define_rule(assertion_method, target_method:, preferred_method: nil, inverse class_eval(<<~RUBY, __FILE__, __LINE__ + 1) include ArgumentRangeHelper + extend AutoCorrector MSG = 'Prefer using `#{preferred_method}(%s)` over ' \ '`#{assertion_method}(%s)`.' @@ -36,23 +37,21 @@ def on_send(node) return unless (arguments = peel_redundant_parentheses_from(node.arguments)) return unless arguments.first.respond_to?(:method?) && arguments.first.method?(:#{target_method}) - add_offense(node, message: offense_message(arguments)) + add_offense(node, message: offense_message(arguments)) do |corrector| + autocorrect(corrector, node, arguments) + end end - def autocorrect(node) - lambda do |corrector| - corrector.replace(node.loc.selector, '#{preferred_method}') - - arguments = peel_redundant_parentheses_from(node.arguments) + def autocorrect(corrector, node, arguments) + corrector.replace(node.loc.selector, '#{preferred_method}') - new_arguments = new_arguments(arguments).join(', ') + new_arguments = new_arguments(arguments).join(', ') - if enclosed_in_redundant_parentheses?(node) - new_arguments = '(' + new_arguments + ')' - end - - corrector.replace(first_argument_range(node), new_arguments) + if enclosed_in_redundant_parentheses?(node) + new_arguments = '(' + new_arguments + ')' end + + corrector.replace(first_argument_range(node), new_arguments) end private diff --git a/test/assertion_helper.rb b/test/assertion_helper.rb index ab6e8fc1..6a74845c 100644 --- a/test/assertion_helper.rb +++ b/test/assertion_helper.rb @@ -16,10 +16,10 @@ def setup def assert_no_offenses(source, file = nil) setup_assertion - inspect_source(source, @cop, file) + offenses = inspect_source(source, @cop, file) expected_annotations = RuboCop::RSpec::ExpectOffense::AnnotatedSource.parse(source) - actual_annotations = expected_annotations.with_offense_annotations(@cop.offenses) + actual_annotations = expected_annotations.with_offense_annotations(offenses) assert_equal(source, actual_annotations.to_s) end @@ -32,20 +32,43 @@ def assert_offense(source, file = nil) expected_annotations = RuboCop::RSpec::ExpectOffense::AnnotatedSource.parse(source) raise 'Use `assert_no_offenses` to assert that no offenses are found' if expected_annotations.plain_source == source - @processed_source = inspect_source(expected_annotations.plain_source, @cop, file) + @processed_source = parse_source!(expected_annotations.plain_source, file) - actual_annotations = expected_annotations.with_offense_annotations(@cop.offenses) + offenses = _investigate(@cop, @processed_source) + + actual_annotations = expected_annotations.with_offense_annotations(offenses) assert_equal(expected_annotations.to_s, actual_annotations.to_s) end - def assert_correction(correction) + def _investigate(cop, processed_source) + team = RuboCop::Cop::Team.new([cop], nil, raise_error: true) + report = team.investigate(processed_source) + @last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source) + report.offenses + end + + def assert_correction(correction, loop: true) raise '`assert_correction` must follow `assert_offense`' unless @processed_source - corrector = RuboCop::Cop::Legacy::Corrector.new( - @processed_source.buffer, @cop.corrections - ) - new_source = corrector.rewrite + iteration = 0 + new_source = loop do + iteration += 1 + + corrected_source = @last_corrector.rewrite + + break corrected_source unless loop + break corrected_source if @last_corrector.empty? || corrected_source == @processed_source.buffer.source + + if iteration > RuboCop::Runner::MAX_ITERATIONS + raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, []) + end + + # Prepare for next loop + @processed_source = parse_source!(corrected_source, @processed_source.path) + + _investigate(@cop, @processed_source) + end assert_equal(correction, new_source) end @@ -57,10 +80,9 @@ def setup_assertion def inspect_source(source, cop, file = nil) processed_source = parse_source!(source, file) + raise 'Error parsing example code' unless processed_source.valid_syntax? - investigate(cop, processed_source) - - processed_source + _investigate(cop, processed_source) end def investigate(cop, processed_source) @@ -81,10 +103,8 @@ def parse_source!(source, file = nil) file.rewind file = file.path end - processed_source = RuboCop::ProcessedSource.new(source, ruby_version, file) - raise 'Error parsing example code' unless processed_source.valid_syntax? - processed_source + RuboCop::ProcessedSource.new(source, ruby_version, file) end def ruby_version