rubocop-minitest 0.32.2 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce290f7a13faed25c00a17d9daf8bcaf17e187599a075323fc99f8494c29c2bb
4
- data.tar.gz: 9def860d52f65aed4e8923bcf2fd851a5188485986c7ad5bce44a9dc0d79b2d3
3
+ metadata.gz: 571b1db9fefc76fa80002c19d3717b845d1db2233f4e42334be77c000e6e4c97
4
+ data.tar.gz: 9e415cf5f10bd9fe304cf4e7e06ddc8e429fd44f8f81736db6399ff49e159014
5
5
  SHA512:
6
- metadata.gz: 8db20fcf7d8e58b564da63b85f6692c4a2be189ffeacdc654f4b18ea689416688442df945606c84f55e63b9007c8df51b4f173004a7ae145603733f6bac62c61
7
- data.tar.gz: 41232dfbabd012e4edbe1e78b49f1846004246950773a6f06c50fff358cb71a79fbdcd95ed0657690387801331093606c2dabb376788368cf51438ff84846be4
6
+ metadata.gz: c4e0adcffeec5f46c694480f7a4d99c04f76545694318c1b660f5dcde4eb6e0626f07bd2d25a9d1042019223cc393fae17555a98fe9d6fbcc567c790cc3aee4d
7
+ data.tar.gz: 4ba96bd280bec762d6256e40f16e40c2831cddb78c7df75ef172c0ca50d6d55ab8ec61499f05cc613cdc9925ab3f370c21bf8bb6f047591b3aae9db45f8117cd
data/README.md CHANGED
@@ -53,6 +53,8 @@ $ rubocop --require rubocop-minitest
53
53
  ### Rake task
54
54
 
55
55
  ```ruby
56
+ require 'rubocop/rake_task'
57
+
56
58
  RuboCop::RakeTask.new do |task|
57
59
  task.requires << 'rubocop-minitest'
58
60
  end
data/config/default.yml CHANGED
@@ -192,12 +192,23 @@ Minitest/NoTestCases:
192
192
  Enabled: false
193
193
  VersionAdded: '0.30'
194
194
 
195
+ Minitest/NonExecutableTestMethod:
196
+ Description: 'Checks uses of test methods outside test class.'
197
+ Enabled: pending
198
+ Severity: warning
199
+ VersionAdded: '0.34'
200
+
195
201
  Minitest/NonPublicTestMethod:
196
202
  Description: 'Detects non `public` (marked as `private` or `protected`) test methods.'
197
203
  Enabled: pending
198
204
  Severity: warning
199
205
  VersionAdded: '0.27'
200
206
 
207
+ Minitest/RedundantMessageArgument:
208
+ Description: 'Detects redundant message argument in assertion methods.'
209
+ Enabled: pending
210
+ VersionAdded: '0.34'
211
+
201
212
  Minitest/RefuteEmpty:
202
213
  Description: 'This cop enforces to use `refute_empty` instead of using `refute(object.empty?)`.'
203
214
  StyleGuide: 'https://minitest.rubystyle.guide#refute-empty'
@@ -22,12 +22,11 @@ module RuboCop
22
22
  remove_method :on_send
23
23
  def on_send(node)
24
24
  return unless node.method?(:assert)
25
- return unless (arguments = peel_redundant_parentheses_from(node.arguments))
26
- return unless arguments.first.respond_to?(:method?) && arguments.first.method?(:empty?)
27
- return unless arguments.first.arguments.empty?
25
+ return unless node.first_argument.respond_to?(:method?) && node.first_argument.method?(:empty?)
26
+ return unless node.first_argument.arguments.empty?
28
27
 
29
- add_offense(node, message: offense_message(arguments)) do |corrector|
30
- autocorrect(corrector, node, arguments)
28
+ add_offense(node, message: offense_message(node.arguments)) do |corrector|
29
+ autocorrect(corrector, node, node.arguments)
31
30
  end
32
31
  end
33
32
  end
@@ -9,14 +9,46 @@ module RuboCop
9
9
  # @example
10
10
  # # bad
11
11
  # assert("rubocop-minitest" == actual)
12
+ # assert_operator("rubocop-minitest", :==, actual)
12
13
  #
13
14
  # # good
14
15
  # assert_equal("rubocop-minitest", actual)
15
16
  #
16
17
  class AssertEqual < Base
17
- extend MinitestCopRule
18
+ include ArgumentRangeHelper
19
+ extend AutoCorrector
18
20
 
19
- define_rule :assert, target_method: :==, preferred_method: :assert_equal
21
+ MSG = 'Prefer using `assert_equal(%<preferred>s)`.'
22
+ RESTRICT_ON_SEND = %i[assert assert_operator].freeze
23
+
24
+ def_node_matcher :assert_equal, <<~PATTERN
25
+ {
26
+ (send nil? :assert (send $_ :== $_) $...)
27
+ (send nil? :assert_operator $_ (sym :==) $_ $...)
28
+ }
29
+ PATTERN
30
+
31
+ # rubocop:disable Metrics/AbcSize
32
+ def on_send(node)
33
+ assert_equal(node) do |expected, actual, rest_args|
34
+ basic_arguments = "#{expected.source}, #{actual.source}"
35
+ preferred = (message_arg = rest_args.first) ? "#{basic_arguments}, #{message_arg.source}" : basic_arguments
36
+ message = format(MSG, preferred: preferred)
37
+
38
+ add_offense(node, message: message) do |corrector|
39
+ corrector.replace(node.loc.selector, 'assert_equal')
40
+
41
+ range = if node.method?(:assert)
42
+ node.first_argument
43
+ else
44
+ node.first_argument.source_range.begin.join(node.arguments[2].source_range.end)
45
+ end
46
+
47
+ corrector.replace(range, basic_arguments)
48
+ end
49
+ end
50
+ end
51
+ # rubocop:enable Metrics/AbcSize
20
52
  end
21
53
  end
22
54
  end
@@ -11,6 +11,7 @@ module RuboCop
11
11
  # assert(matcher.match(string))
12
12
  # assert(matcher.match?(string))
13
13
  # assert(matcher =~ string)
14
+ # assert_operator(matcher, :=~, string)
14
15
  # assert(matcher.match(string), 'message')
15
16
  #
16
17
  # # good
@@ -18,10 +19,50 @@ module RuboCop
18
19
  # assert_match(matcher, string, 'message')
19
20
  #
20
21
  class AssertMatch < Base
21
- extend MinitestCopRule
22
+ include ArgumentRangeHelper
23
+ extend AutoCorrector
22
24
 
23
- define_rule :assert, target_method: %i[match match? =~],
24
- preferred_method: :assert_match, inverse: 'regexp_type?'
25
+ MSG = 'Prefer using `assert_match(%<preferred>s)`.'
26
+ RESTRICT_ON_SEND = %i[assert assert_operator].freeze
27
+
28
+ def_node_matcher :assert_match, <<~PATTERN
29
+ {
30
+ (send nil? :assert (send $_ {:match :match? :=~} $_) $...)
31
+ (send nil? :assert_operator $_ (sym :=~) $_ $...)
32
+ }
33
+ PATTERN
34
+
35
+ # rubocop:disable Metrics/AbcSize
36
+ def on_send(node)
37
+ assert_match(node) do |expected, actual, rest_args|
38
+ basic_arguments = order_expected_and_actual(expected, actual)
39
+ preferred = (message_arg = rest_args.first) ? "#{basic_arguments}, #{message_arg.source}" : basic_arguments
40
+ message = format(MSG, preferred: preferred)
41
+
42
+ add_offense(node, message: message) do |corrector|
43
+ corrector.replace(node.loc.selector, 'assert_match')
44
+
45
+ range = if node.method?(:assert)
46
+ node.first_argument
47
+ else
48
+ node.first_argument.source_range.begin.join(node.arguments[2].source_range.end)
49
+ end
50
+
51
+ corrector.replace(range, basic_arguments)
52
+ end
53
+ end
54
+ end
55
+ # rubocop:enable Metrics/AbcSize
56
+
57
+ private
58
+
59
+ def order_expected_and_actual(expected, actual)
60
+ if actual.regexp_type?
61
+ [actual, expected]
62
+ else
63
+ [expected, actual]
64
+ end.map(&:source).join(', ')
65
+ end
25
66
  end
26
67
  end
27
68
  end
@@ -40,7 +40,7 @@ module RuboCop
40
40
 
41
41
  def build_new_arguments(node)
42
42
  lhs, op, rhs = *node.first_argument
43
- new_arguments = "#{lhs.source}, :#{op}, #{rhs.source}"
43
+ new_arguments = +"#{lhs.source}, :#{op}, #{rhs.source}"
44
44
 
45
45
  if node.arguments.count == 2
46
46
  new_arguments << ", #{node.last_argument.source}"
@@ -12,14 +12,58 @@ module RuboCop
12
12
  # @example
13
13
  # # bad
14
14
  # assert(expected.equal?(actual))
15
+ # assert_equal(expected.object_id, actual.object_id)
15
16
  #
16
17
  # # good
17
18
  # assert_same(expected, actual)
18
19
  #
19
20
  class AssertSame < Base
20
- extend MinitestCopRule
21
+ extend AutoCorrector
21
22
 
22
- define_rule :assert, target_method: :equal?, preferred_method: :assert_same
23
+ MSG = 'Prefer using `assert_same(%<new_arguments>s)`.'
24
+ RESTRICT_ON_SEND = %i[assert assert_equal].freeze
25
+
26
+ def_node_matcher :assert_with_equal?, <<~PATTERN
27
+ (send nil? :assert
28
+ $(send $_ :equal? $_)
29
+ $_?)
30
+ PATTERN
31
+
32
+ def_node_matcher :assert_equal_with_object_id?, <<~PATTERN
33
+ (send nil? :assert_equal
34
+ (send $_ :object_id)
35
+ (send $_ :object_id)
36
+ $_?)
37
+ PATTERN
38
+
39
+ # rubocop:disable Metrics/AbcSize
40
+ def on_send(node)
41
+ if (equal_node, expected_node, actual_node, message_node = assert_with_equal?(node))
42
+ add_offense(node, message: message(expected_node, actual_node, message_node.first)) do |corrector|
43
+ corrector.replace(node.loc.selector, 'assert_same')
44
+ corrector.replace(equal_node, "#{expected_node.source}, #{actual_node.source}")
45
+ end
46
+ elsif (expected_node, actual_node, message_node = assert_equal_with_object_id?(node))
47
+ add_offense(node, message: message(expected_node, actual_node, message_node.first)) do |corrector|
48
+ corrector.replace(node.loc.selector, 'assert_same')
49
+ remove_method_call(expected_node.parent, corrector)
50
+ remove_method_call(actual_node.parent, corrector)
51
+ end
52
+ end
53
+ end
54
+ # rubocop:enable Metrics/AbcSize
55
+
56
+ private
57
+
58
+ def message(expected_node, actual_node, message_node)
59
+ arguments = [expected_node, actual_node, message_node].compact.map(&:source).join(', ')
60
+ format(MSG, new_arguments: arguments)
61
+ end
62
+
63
+ def remove_method_call(send_node, corrector)
64
+ range = send_node.loc.dot.join(send_node.loc.selector)
65
+ corrector.remove(range)
66
+ end
23
67
  end
24
68
  end
25
69
  end
@@ -30,7 +30,7 @@ module RuboCop
30
30
  return if node.parent.resbody_type?
31
31
  return if accept_previous_line?(previous_line_node, assertion_method)
32
32
 
33
- previous_line_node = previous_line_node.arguments.last if use_heredoc_argument?(previous_line_node)
33
+ previous_line_node = previous_line_node.last_argument if use_heredoc_argument?(previous_line_node)
34
34
  return if use_assertion_method_at_last_of_block?(previous_line_node)
35
35
  return unless no_empty_line?(previous_line_node, assertion_method)
36
36
 
@@ -57,7 +57,7 @@ module RuboCop
57
57
  end
58
58
 
59
59
  def use_heredoc_argument?(node)
60
- node.respond_to?(:arguments) && heredoc?(node.arguments.last)
60
+ node.respond_to?(:arguments) && heredoc?(node.last_argument)
61
61
  end
62
62
 
63
63
  def use_assertion_method_at_last_of_block?(node)
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # Checks for the use of test methods outside of a test class.
7
+ #
8
+ # Test methods should be defined within a test class to ensure their execution.
9
+ #
10
+ # NOTE: This cop assumes that classes whose superclass name includes the word
11
+ # "`Test`" are test classes, in order to prevent false positives.
12
+ #
13
+ # @example
14
+ #
15
+ # # bad
16
+ # class FooTest < Minitest::Test
17
+ # end
18
+ # def test_method_should_be_inside_test_class
19
+ # end
20
+ #
21
+ # # good
22
+ # class FooTest < Minitest::Test
23
+ # def test_method_should_be_inside_test_class
24
+ # end
25
+ # end
26
+ #
27
+ class NonExecutableTestMethod < Base
28
+ include MinitestExplorationHelpers
29
+
30
+ MSG = 'Test method should be defined inside a test class to ensure execution.'
31
+
32
+ def on_def(node)
33
+ return if !test_method?(node) || !use_test_class?
34
+ return if node.left_siblings.none? { |sibling| possible_test_class?(sibling) }
35
+
36
+ add_offense(node)
37
+ end
38
+
39
+ def use_test_class?
40
+ root_node = processed_source.ast
41
+
42
+ root_node.each_descendant(:class).any? { |class_node| test_class?(class_node) }
43
+ end
44
+
45
+ def possible_test_class?(node)
46
+ node.is_a?(AST::ClassNode) && test_class?(node) && node.parent_class.source.include?('Test')
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # Detects redundant message argument in assertion methods.
7
+ # The message argument `nil` is redundant because it is the default value.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ # assert_equal(expected, actual, nil)
13
+ #
14
+ # # good
15
+ # assert_equal(expected, actual)
16
+ # assert_equal(expected, actual, 'message')
17
+ #
18
+ class RedundantMessageArgument < Base
19
+ extend AutoCorrector
20
+
21
+ MSG = 'Remove the redundant message argument.'
22
+
23
+ RESTRICT_ON_SEND = %i[
24
+ assert assert_empty assert_equal assert_same assert_in_delta assert_in_epsilon assert_includes
25
+ assert_instance_of assert_kind_of assert_match assert_nil assert_operator assert_path_exists
26
+ assert_predicate assert_respond_to assert_same assert_throws
27
+ flunk
28
+ refute refute_empty refute_equal refute_in_delta refute_in_epsilon refute_includes
29
+ refute_instance_of refute_kind_of refute_match refute_nil refute_operator refute_path_exists
30
+ refute_predicate refute_respond_to refute_same
31
+ ].freeze
32
+
33
+ # @!method bad_method?(node)
34
+ def_node_matcher :redundant_message_argument, <<~PATTERN
35
+ {
36
+ (send nil? :assert _ $nil)
37
+ (send nil? :assert_empty _ $nil)
38
+ (send nil? :assert_equal _ _ $nil)
39
+ (send nil? :assert_in_delta _ _ _ $nil)
40
+ (send nil? :assert_in_epsilon _ _ _ $nil)
41
+ (send nil? :assert_includes _ _ $nil)
42
+ (send nil? :assert_instance_of _ _ $nil)
43
+ (send nil? :assert_kind_of _ _ $nil)
44
+ (send nil? :assert_match _ _ $nil)
45
+ (send nil? :assert_nil _ $nil)
46
+ (send nil? :assert_operator _ _ _ $nil)
47
+ (send nil? :assert_path_exists _ $nil)
48
+ (send nil? :assert_predicate _ _ $nil)
49
+ (send nil? :assert_respond_to _ _ $nil)
50
+ (send nil? :assert_same _ _ $nil)
51
+ (send nil? :assert_throws _ $nil)
52
+ (send nil? :flunk $nil)
53
+ (send nil? :refute _ $nil)
54
+ (send nil? :refute_empty _ $nil)
55
+ (send nil? :refute_equal _ _ $nil)
56
+ (send nil? :refute_in_delta _ _ _ $nil)
57
+ (send nil? :refute_in_epsilon _ _ _ $nil)
58
+ (send nil? :refute_includes _ _ $nil)
59
+ (send nil? :refute_instance_of _ _ $nil)
60
+ (send nil? :refute_kind_of _ _ $nil)
61
+ (send nil? :refute_match _ _ $nil)
62
+ (send nil? :refute_nil _ $nil)
63
+ (send nil? :refute_operator _ _ _ $nil)
64
+ (send nil? :refute_path_exists _ $nil)
65
+ (send nil? :refute_predicate _ _ $nil)
66
+ (send nil? :refute_respond_to _ _ $nil)
67
+ (send nil? :refute_same _ _ $nil)
68
+ }
69
+ PATTERN
70
+
71
+ def on_send(node)
72
+ return unless (redundant_message_argument = redundant_message_argument(node))
73
+
74
+ add_offense(redundant_message_argument) do |corrector|
75
+ if node.arguments.one?
76
+ range = redundant_message_argument
77
+ else
78
+ index = node.arguments.index(redundant_message_argument)
79
+ range = node.arguments[index - 1].source_range.end.join(redundant_message_argument.source_range.end)
80
+ end
81
+
82
+ corrector.remove(range)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -22,12 +22,11 @@ module RuboCop
22
22
  remove_method :on_send
23
23
  def on_send(node)
24
24
  return unless node.method?(:refute)
25
- return unless (arguments = peel_redundant_parentheses_from(node.arguments))
26
- return unless arguments.first.respond_to?(:method?) && arguments.first.method?(:empty?)
27
- return unless arguments.first.arguments.empty?
25
+ return unless node.first_argument.respond_to?(:method?) && node.first_argument.method?(:empty?)
26
+ return unless node.first_argument.arguments.empty?
28
27
 
29
- add_offense(node, message: offense_message(arguments)) do |corrector|
30
- autocorrect(corrector, node, arguments)
28
+ add_offense(node, message: offense_message(node.arguments)) do |corrector|
29
+ autocorrect(corrector, node, node.arguments)
31
30
  end
32
31
  end
33
32
  end
@@ -9,6 +9,9 @@ module RuboCop
9
9
  # @example
10
10
  # # bad
11
11
  # assert("rubocop-minitest" != actual)
12
+ # refute("rubocop-minitest" == actual)
13
+ # assert_operator("rubocop-minitest", :!=, actual)
14
+ # refute_operator("rubocop-minitest", :==, actual)
12
15
  #
13
16
  # # good
14
17
  # refute_equal("rubocop-minitest", actual)
@@ -18,45 +21,38 @@ module RuboCop
18
21
  extend AutoCorrector
19
22
 
20
23
  MSG = 'Prefer using `refute_equal(%<preferred>s)`.'
21
- RESTRICT_ON_SEND = %i[assert].freeze
22
-
23
- def_node_matcher :assert_not_equal, <<~PATTERN
24
- (send nil? :assert (send $_ :!= $_) $... )
24
+ RESTRICT_ON_SEND = %i[assert refute assert_operator refute_operator].freeze
25
+
26
+ def_node_matcher :refute_equal, <<~PATTERN
27
+ {
28
+ (send nil? :assert (send $_ :!= $_) $...)
29
+ (send nil? :refute (send $_ :== $_) $...)
30
+ (send nil? :assert_operator $_ (sym :!=) $_ $...)
31
+ (send nil? :refute_operator $_ (sym :==) $_ $...)
32
+ }
25
33
  PATTERN
26
34
 
35
+ # rubocop:disable Metrics/AbcSize
27
36
  def on_send(node)
28
- preferred = process_not_equal(node)
29
- return unless preferred
30
-
31
- assert_not_equal(node) do |expected, actual|
37
+ refute_equal(node) do |expected, actual, rest_args|
38
+ basic_arguments = "#{expected.source}, #{actual.source}"
39
+ preferred = (message_arg = rest_args.first) ? "#{basic_arguments}, #{message_arg.source}" : basic_arguments
32
40
  message = format(MSG, preferred: preferred)
33
41
 
34
42
  add_offense(node, message: message) do |corrector|
35
43
  corrector.replace(node.loc.selector, 'refute_equal')
36
44
 
37
- replacement = [expected, actual].map(&:source).join(', ')
38
- corrector.replace(node.first_argument, replacement)
39
- end
40
- end
41
- end
42
-
43
- private
45
+ range = if node.method?(:assert) || node.method?(:refute)
46
+ node.first_argument
47
+ else
48
+ node.first_argument.source_range.begin.join(node.arguments[2].source_range.end)
49
+ end
44
50
 
45
- def preferred_usage(first_arg, second_arg, custom_message = nil)
46
- [first_arg, second_arg, custom_message].compact.map(&:source).join(', ')
47
- end
48
-
49
- def original_usage(first_part, custom_message)
50
- [first_part, custom_message].compact.join(', ')
51
- end
52
-
53
- def process_not_equal(node)
54
- assert_not_equal(node) do |first_arg, second_arg, rest_args|
55
- custom_message = rest_args.first
56
-
57
- preferred_usage(first_arg, second_arg, custom_message)
51
+ corrector.replace(range, basic_arguments)
52
+ end
58
53
  end
59
54
  end
55
+ # rubocop:enable Metrics/AbcSize
60
56
  end
61
57
  end
62
58
  end
@@ -11,6 +11,8 @@ module RuboCop
11
11
  # refute(matcher.match(string))
12
12
  # refute(matcher.match?(string))
13
13
  # refute(matcher =~ string)
14
+ # refute_operator(matcher, :=~, string)
15
+ # assert_operator(matcher, :!~, string)
14
16
  # refute(matcher.match(string), 'message')
15
17
  #
16
18
  # # good
@@ -18,10 +20,51 @@ module RuboCop
18
20
  # refute_match(matcher, string, 'message')
19
21
  #
20
22
  class RefuteMatch < Base
21
- extend MinitestCopRule
23
+ include ArgumentRangeHelper
24
+ extend AutoCorrector
22
25
 
23
- define_rule :refute, target_method: %i[match match? =~],
24
- preferred_method: :refute_match, inverse: 'regexp_type?'
26
+ MSG = 'Prefer using `refute_match(%<preferred>s)`.'
27
+ RESTRICT_ON_SEND = %i[refute refute_operator assert_operator].freeze
28
+
29
+ def_node_matcher :refute_match, <<~PATTERN
30
+ {
31
+ (send nil? :refute (send $_ {:match :match? :=~} $_) $...)
32
+ (send nil? :refute_operator $_ (sym :=~) $_ $...)
33
+ (send nil? :assert_operator $_ (sym :!~) $_ $...)
34
+ }
35
+ PATTERN
36
+
37
+ # rubocop:disable Metrics/AbcSize
38
+ def on_send(node)
39
+ refute_match(node) do |expected, actual, rest_args|
40
+ basic_arguments = order_expected_and_actual(expected, actual)
41
+ preferred = (message_arg = rest_args.first) ? "#{basic_arguments}, #{message_arg.source}" : basic_arguments
42
+ message = format(MSG, preferred: preferred)
43
+
44
+ add_offense(node, message: message) do |corrector|
45
+ corrector.replace(node.loc.selector, 'refute_match')
46
+
47
+ range = if node.method?(:refute)
48
+ node.first_argument
49
+ else
50
+ node.first_argument.source_range.begin.join(node.arguments[2].source_range.end)
51
+ end
52
+
53
+ corrector.replace(range, basic_arguments)
54
+ end
55
+ end
56
+ end
57
+ # rubocop:enable Metrics/AbcSize
58
+
59
+ private
60
+
61
+ def order_expected_and_actual(expected, actual)
62
+ if actual.regexp_type?
63
+ [actual, expected]
64
+ else
65
+ [expected, actual]
66
+ end.map(&:source).join(', ')
67
+ end
25
68
  end
26
69
  end
27
70
  end
@@ -40,7 +40,7 @@ module RuboCop
40
40
 
41
41
  def build_new_arguments(node)
42
42
  lhs, op, rhs = *node.first_argument
43
- new_arguments = "#{lhs.source}, :#{op}, #{rhs.source}"
43
+ new_arguments = +"#{lhs.source}, :#{op}, #{rhs.source}"
44
44
 
45
45
  if node.arguments.count == 2
46
46
  new_arguments << ", #{node.last_argument.source}"
@@ -12,14 +12,58 @@ module RuboCop
12
12
  # @example
13
13
  # # bad
14
14
  # refute(expected.equal?(actual))
15
+ # refute_equal(expected.object_id, actual.object_id)
15
16
  #
16
17
  # # good
17
18
  # refute_same(expected, actual)
18
19
  #
19
20
  class RefuteSame < Base
20
- extend MinitestCopRule
21
+ extend AutoCorrector
21
22
 
22
- define_rule :refute, target_method: :equal?, preferred_method: :refute_same
23
+ MSG = 'Prefer using `refute_same(%<new_arguments>s)`.'
24
+ RESTRICT_ON_SEND = %i[refute refute_equal].freeze
25
+
26
+ def_node_matcher :refute_with_equal?, <<~PATTERN
27
+ (send nil? :refute
28
+ $(send $_ :equal? $_)
29
+ $_?)
30
+ PATTERN
31
+
32
+ def_node_matcher :refute_equal_with_object_id?, <<~PATTERN
33
+ (send nil? :refute_equal
34
+ (send $_ :object_id)
35
+ (send $_ :object_id)
36
+ $_?)
37
+ PATTERN
38
+
39
+ # rubocop:disable Metrics/AbcSize
40
+ def on_send(node)
41
+ if (equal_node, expected_node, actual_node, message_node = refute_with_equal?(node))
42
+ add_offense(node, message: message(expected_node, actual_node, message_node.first)) do |corrector|
43
+ corrector.replace(node.loc.selector, 'refute_same')
44
+ corrector.replace(equal_node, "#{expected_node.source}, #{actual_node.source}")
45
+ end
46
+ elsif (expected_node, actual_node, message_node = refute_equal_with_object_id?(node))
47
+ add_offense(node, message: message(expected_node, actual_node, message_node.first)) do |corrector|
48
+ corrector.replace(node.loc.selector, 'refute_same')
49
+ remove_method_call(expected_node.parent, corrector)
50
+ remove_method_call(actual_node.parent, corrector)
51
+ end
52
+ end
53
+ end
54
+ # rubocop:enable Metrics/AbcSize
55
+
56
+ private
57
+
58
+ def message(expected_node, actual_node, message_node)
59
+ arguments = [expected_node, actual_node, message_node].compact.map(&:source).join(', ')
60
+ format(MSG, new_arguments: arguments)
61
+ end
62
+
63
+ def remove_method_call(send_node, corrector)
64
+ range = send_node.loc.dot.join(send_node.loc.selector)
65
+ corrector.remove(range)
66
+ end
23
67
  end
24
68
  end
25
69
  end
@@ -30,6 +30,8 @@ require_relative 'minitest/assert_silent'
30
30
  require_relative 'minitest/assert_truthy'
31
31
  require_relative 'minitest/duplicate_test_run'
32
32
  require_relative 'minitest/empty_line_before_assertion_methods'
33
+ require_relative 'minitest/non_executable_test_method'
34
+ require_relative 'minitest/redundant_message_argument'
33
35
  require_relative 'minitest/return_in_test_method'
34
36
  require_relative 'minitest/test_file_name'
35
37
  require_relative 'minitest/global_expectations'
@@ -18,7 +18,7 @@ module RuboCop
18
18
 
19
19
  def all_arguments_range(node)
20
20
  first_argument = node.first_argument
21
- last_argument = node.arguments.last
21
+ last_argument = node.last_argument
22
22
 
23
23
  range_between(first_argument.source_range.begin_pos, last_argument.source_range.end_pos)
24
24
  end
@@ -45,13 +45,12 @@ module RuboCop
45
45
 
46
46
  def on_send(node)
47
47
  return unless node.method?(:#{assertion_method})
48
- return unless (arguments = peel_redundant_parentheses_from(node.arguments))
49
- return unless arguments.first&.call_type?
50
- return if arguments.first.arguments.empty? ||
51
- #{target_methods}.none? { |target_method| arguments.first.method?(target_method) }
48
+ return unless node.arguments.first&.call_type?
49
+ return if node.arguments.first.arguments.empty? ||
50
+ #{target_methods}.none? { |target_method| node.arguments.first.method?(target_method) }
52
51
 
53
- add_offense(node, message: offense_message(arguments)) do |corrector|
54
- autocorrect(corrector, node, arguments)
52
+ add_offense(node, message: offense_message(node.arguments)) do |corrector|
53
+ autocorrect(corrector, node, node.arguments)
55
54
  end
56
55
  end
57
56
 
@@ -60,21 +59,11 @@ module RuboCop
60
59
 
61
60
  new_arguments = new_arguments(arguments).join(', ')
62
61
 
63
- if enclosed_in_redundant_parentheses?(node)
64
- new_arguments = '(' + new_arguments + ')'
65
- end
66
-
67
62
  corrector.replace(node.first_argument, new_arguments)
68
63
  end
69
64
 
70
65
  private
71
66
 
72
- def peel_redundant_parentheses_from(arguments)
73
- return arguments unless arguments.first&.begin_type?
74
-
75
- peel_redundant_parentheses_from(arguments.first.children)
76
- end
77
-
78
67
  def offense_message(arguments)
79
68
  message_argument = arguments.last if arguments.first != arguments.last
80
69
 
@@ -103,10 +92,6 @@ module RuboCop
103
92
  new_arguments
104
93
  end
105
94
 
106
- def enclosed_in_redundant_parentheses?(node)
107
- node.arguments.first.begin_type?
108
- end
109
-
110
95
  def correct_receiver(receiver)
111
96
  receiver ? receiver.source : 'self'
112
97
  end
@@ -100,6 +100,7 @@ module RuboCop
100
100
  end
101
101
 
102
102
  def assertion_method?(node)
103
+ return assertion_method?(node.expression) if node.assignment?
103
104
  return false if !node.send_type? && !node.block_type? && !node.numblock_type?
104
105
 
105
106
  ASSERTION_PREFIXES.any? do |prefix|
@@ -9,17 +9,13 @@ module RuboCop
9
9
  MSG = 'Prefer using `%<assertion_type>s_predicate(%<new_arguments>s)`.'
10
10
 
11
11
  def on_send(node)
12
- return unless (arguments = peel_redundant_parentheses_from(node.arguments))
12
+ return unless node.first_argument
13
+ return if node.first_argument.block_type? || node.first_argument.numblock_type?
14
+ return unless predicate_method?(node.first_argument)
15
+ return unless node.first_argument.arguments.count.zero?
13
16
 
14
- first_argument = arguments.first
15
-
16
- return unless first_argument
17
- return if first_argument.block_type? || first_argument.numblock_type?
18
- return unless predicate_method?(first_argument)
19
- return unless first_argument.arguments.count.zero?
20
-
21
- add_offense(node, message: offense_message(arguments)) do |corrector|
22
- autocorrect(corrector, node, arguments)
17
+ add_offense(node, message: offense_message(node.arguments)) do |corrector|
18
+ autocorrect(corrector, node, node.arguments)
23
19
  end
24
20
  end
25
21
 
@@ -33,12 +29,6 @@ module RuboCop
33
29
 
34
30
  private
35
31
 
36
- def peel_redundant_parentheses_from(arguments)
37
- return arguments unless arguments.first&.begin_type?
38
-
39
- peel_redundant_parentheses_from(arguments.first.children)
40
- end
41
-
42
32
  def predicate_method?(first_argument)
43
33
  first_argument.respond_to?(:predicate_method?) && first_argument.predicate_method?
44
34
  end
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Minitest
5
5
  # This module holds the RuboCop Minitest version information.
6
6
  module Version
7
- STRING = '0.32.2'
7
+ STRING = '0.34.0'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-minitest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.2
4
+ version: 0.34.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2023-09-27 00:00:00.000000000 Z
13
+ date: 2023-12-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -32,6 +32,26 @@ dependencies:
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
34
  version: '2.0'
35
+ - !ruby/object:Gem::Dependency
36
+ name: rubocop-ast
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 1.30.0
42
+ - - "<"
43
+ - !ruby/object:Gem::Version
44
+ version: '2.0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 1.30.0
52
+ - - "<"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
35
55
  description: |
36
56
  Automatic Minitest code style checking tool.
37
57
  A RuboCop extension focused on enforcing Minitest best practices and coding conventions.
@@ -74,7 +94,9 @@ files:
74
94
  - lib/rubocop/cop/minitest/multiple_assertions.rb
75
95
  - lib/rubocop/cop/minitest/no_assertions.rb
76
96
  - lib/rubocop/cop/minitest/no_test_cases.rb
97
+ - lib/rubocop/cop/minitest/non_executable_test_method.rb
77
98
  - lib/rubocop/cop/minitest/non_public_test_method.rb
99
+ - lib/rubocop/cop/minitest/redundant_message_argument.rb
78
100
  - lib/rubocop/cop/minitest/refute_empty.rb
79
101
  - lib/rubocop/cop/minitest/refute_equal.rb
80
102
  - lib/rubocop/cop/minitest/refute_false.rb
@@ -117,7 +139,7 @@ metadata:
117
139
  homepage_uri: https://docs.rubocop.org/rubocop-minitest/
118
140
  changelog_uri: https://github.com/rubocop/rubocop-minitest/blob/master/CHANGELOG.md
119
141
  source_code_uri: https://github.com/rubocop/rubocop-minitest
120
- documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.32
142
+ documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.34
121
143
  bug_tracker_uri: https://github.com/rubocop/rubocop-minitest/issues
122
144
  rubygems_mfa_required: 'true'
123
145
  post_install_message:
@@ -135,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
157
  - !ruby/object:Gem::Version
136
158
  version: '0'
137
159
  requirements: []
138
- rubygems_version: 3.4.19
160
+ rubygems_version: 3.1.6
139
161
  signing_key:
140
162
  specification_version: 4
141
163
  summary: Automatic Minitest code style checking tool.