rubocop-minitest 0.11.0 → 0.14.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +0 -3
  3. data/.rubocop.yml +14 -1
  4. data/CHANGELOG.md +34 -0
  5. data/Gemfile +1 -1
  6. data/config/default.yml +11 -0
  7. data/docs/antora.yml +1 -1
  8. data/docs/modules/ROOT/pages/cops.adoc +2 -0
  9. data/docs/modules/ROOT/pages/cops_minitest.adoc +68 -1
  10. data/lib/rubocop/cop/minitest/assert_empty.rb +1 -1
  11. data/lib/rubocop/cop/minitest/assert_empty_literal.rb +4 -9
  12. data/lib/rubocop/cop/minitest/assert_equal.rb +1 -1
  13. data/lib/rubocop/cop/minitest/assert_in_delta.rb +2 -1
  14. data/lib/rubocop/cop/minitest/assert_includes.rb +1 -1
  15. data/lib/rubocop/cop/minitest/assert_instance_of.rb +1 -1
  16. data/lib/rubocop/cop/minitest/assert_kind_of.rb +1 -1
  17. data/lib/rubocop/cop/minitest/assert_match.rb +1 -1
  18. data/lib/rubocop/cop/minitest/assert_nil.rb +4 -11
  19. data/lib/rubocop/cop/minitest/assert_output.rb +1 -1
  20. data/lib/rubocop/cop/minitest/assert_path_exists.rb +5 -12
  21. data/lib/rubocop/cop/minitest/assert_respond_to.rb +1 -1
  22. data/lib/rubocop/cop/minitest/assert_silent.rb +8 -6
  23. data/lib/rubocop/cop/minitest/assert_truthy.rb +4 -11
  24. data/lib/rubocop/cop/minitest/assert_with_expected_argument.rb +4 -1
  25. data/lib/rubocop/cop/minitest/assertion_in_lifecycle_hook.rb +1 -1
  26. data/lib/rubocop/cop/minitest/global_expectations.rb +4 -7
  27. data/lib/rubocop/cop/minitest/literal_as_actual_argument.rb +14 -14
  28. data/lib/rubocop/cop/minitest/multiple_assertions.rb +2 -2
  29. data/lib/rubocop/cop/minitest/no_assertions.rb +48 -0
  30. data/lib/rubocop/cop/minitest/refute_empty.rb +1 -1
  31. data/lib/rubocop/cop/minitest/refute_equal.rb +5 -7
  32. data/lib/rubocop/cop/minitest/refute_false.rb +16 -26
  33. data/lib/rubocop/cop/minitest/refute_in_delta.rb +2 -1
  34. data/lib/rubocop/cop/minitest/refute_includes.rb +1 -1
  35. data/lib/rubocop/cop/minitest/refute_instance_of.rb +1 -1
  36. data/lib/rubocop/cop/minitest/refute_kind_of.rb +1 -1
  37. data/lib/rubocop/cop/minitest/refute_match.rb +1 -1
  38. data/lib/rubocop/cop/minitest/refute_nil.rb +3 -8
  39. data/lib/rubocop/cop/minitest/refute_path_exists.rb +5 -12
  40. data/lib/rubocop/cop/minitest/refute_respond_to.rb +1 -1
  41. data/lib/rubocop/cop/minitest/test_method_name.rb +8 -7
  42. data/lib/rubocop/cop/minitest/unreachable_assertion.rb +42 -0
  43. data/lib/rubocop/cop/minitest/unspecified_exception.rb +1 -1
  44. data/lib/rubocop/cop/minitest_cops.rb +2 -0
  45. data/lib/rubocop/cop/mixin/in_delta_mixin.rb +5 -15
  46. data/lib/rubocop/cop/mixin/minitest_cop_rule.rb +11 -12
  47. data/lib/rubocop/cop/mixin/minitest_exploration_helpers.rb +14 -4
  48. data/lib/rubocop/minitest/version.rb +1 -1
  49. data/relnotes/v0.11.1.md +5 -0
  50. data/relnotes/v0.12.0.md +10 -0
  51. data/relnotes/v0.12.1.md +5 -0
  52. data/relnotes/v0.13.0.md +5 -0
  53. data/relnotes/v0.14.0.md +5 -0
  54. data/rubocop-minitest.gemspec +1 -1
  55. data/tasks/cops_documentation.rake +11 -14
  56. metadata +12 -5
@@ -15,8 +15,9 @@ module RuboCop
15
15
  # assert(actual)
16
16
  # assert(actual, 'message')
17
17
  #
18
- class AssertTruthy < Cop
18
+ class AssertTruthy < Base
19
19
  include ArgumentRangeHelper
20
+ extend AutoCorrector
20
21
 
21
22
  MSG = 'Prefer using `assert(%<arguments>s)` over ' \
22
23
  '`assert_equal(true, %<arguments>s)`.'
@@ -32,17 +33,9 @@ module RuboCop
32
33
 
33
34
  arguments = [actual.source, message&.source].compact.join(', ')
34
35
 
35
- add_offense(node, message: format(MSG, arguments: arguments))
36
- end
37
- end
38
-
39
- def autocorrect(node)
40
- lambda do |corrector|
41
- assert_equal_with_truthy(node) do |actual|
36
+ add_offense(node, message: format(MSG, arguments: arguments)) do |corrector|
42
37
  corrector.replace(node.loc.selector, 'assert')
43
- corrector.replace(
44
- first_and_second_arguments_range(node), actual.source
45
- )
38
+ corrector.replace(first_and_second_arguments_range(node), actual.source)
46
39
  end
47
40
  end
48
41
  end
@@ -6,6 +6,9 @@ module RuboCop
6
6
  # This cop tries to detect when a user accidentally used
7
7
  # `assert` when they meant to use `assert_equal`.
8
8
  #
9
+ # It is marked as unsafe because it is not possible to determine
10
+ # whether the second argument of `assert` is a message or not.
11
+ #
9
12
  # @example
10
13
  # # bad
11
14
  # assert(3, my_list.length)
@@ -16,7 +19,7 @@ module RuboCop
16
19
  # assert_equal(expected, actual)
17
20
  # assert(foo, 'message')
18
21
  #
19
- class AssertWithExpectedArgument < Cop
22
+ class AssertWithExpectedArgument < Base
20
23
  MSG = 'Did you mean to use `assert_equal(%<arguments>s)`?'
21
24
  RESTRICT_ON_SEND = %i[assert].freeze
22
25
 
@@ -20,7 +20,7 @@ module RuboCop
20
20
  # end
21
21
  # end
22
22
  #
23
- class AssertionInLifecycleHook < Cop
23
+ class AssertionInLifecycleHook < Base
24
24
  include MinitestExplorationHelpers
25
25
 
26
26
  MSG = 'Do not use `%<assertion>s` in `%<hook>s` hook.'
@@ -16,7 +16,9 @@ module RuboCop
16
16
  # _(musts).must_equal expected_musts
17
17
  # _(wonts).wont_match expected_wonts
18
18
  # _ { musts }.must_raise TypeError
19
- class GlobalExpectations < Cop
19
+ class GlobalExpectations < Base
20
+ extend AutoCorrector
21
+
20
22
  MSG = 'Use `%<preferred>s` instead.'
21
23
 
22
24
  VALUE_MATCHERS = %i[
@@ -64,13 +66,8 @@ module RuboCop
64
66
  return unless value_global_expectation?(node) || block_global_expectation?(node)
65
67
 
66
68
  message = format(MSG, preferred: preferred_receiver(node))
67
- add_offense(node, location: node.receiver.source_range, message: message)
68
- end
69
-
70
- def autocorrect(node)
71
- return unless value_global_expectation?(node) || block_global_expectation?(node)
72
69
 
73
- lambda do |corrector|
70
+ add_offense(node.receiver.source_range, message: message) do |corrector|
74
71
  receiver = node.receiver.source_range
75
72
 
76
73
  if BLOCK_MATCHERS.include?(node.method_name)
@@ -17,8 +17,9 @@ module RuboCop
17
17
  # assert_equal [1, 2], foo
18
18
  # assert_equal [1, 2], foo, 'message'
19
19
  #
20
- class LiteralAsActualArgument < Cop
20
+ class LiteralAsActualArgument < Base
21
21
  include ArgumentRangeHelper
22
+ extend AutoCorrector
22
23
 
23
24
  MSG = 'Replace the literal with the first argument.'
24
25
  RESTRICT_ON_SEND = %i[assert_equal].freeze
@@ -27,25 +28,24 @@ module RuboCop
27
28
  return unless node.method?(:assert_equal)
28
29
 
29
30
  actual = node.arguments[1]
30
- return unless actual
31
+ return unless actual&.recursive_basic_literal?
31
32
 
32
- add_offense(node, location: all_arguments_range(node)) if actual.recursive_basic_literal?
33
+ add_offense(all_arguments_range(node)) do |corrector|
34
+ autocorrect(corrector, node)
35
+ end
33
36
  end
34
37
 
35
- def autocorrect(node)
38
+ def autocorrect(corrector, node)
36
39
  expected, actual, message = *node.arguments
37
40
 
38
- lambda do |corrector|
39
- new_actual_source =
40
- if actual.hash_type? && !actual.braces?
41
- "{#{actual.source}}"
42
- else
43
- actual.source
44
- end
45
- arguments = [new_actual_source, expected.source, message&.source].compact.join(', ')
41
+ new_actual_source = if actual.hash_type? && !actual.braces?
42
+ "{#{actual.source}}"
43
+ else
44
+ actual.source
45
+ end
46
+ arguments = [new_actual_source, expected.source, message&.source].compact.join(', ')
46
47
 
47
- corrector.replace(node, "assert_equal(#{arguments})")
48
- end
48
+ corrector.replace(node, "assert_equal(#{arguments})")
49
49
  end
50
50
  end
51
51
  end
@@ -26,7 +26,7 @@ module RuboCop
26
26
  # end
27
27
  # end
28
28
  #
29
- class MultipleAssertions < Cop
29
+ class MultipleAssertions < Base
30
30
  include ConfigurableMax
31
31
  include MinitestExplorationHelpers
32
32
 
@@ -43,7 +43,7 @@ module RuboCop
43
43
  self.max = assertions_count
44
44
 
45
45
  message = format(MSG, total: assertions_count, max: max_assertions)
46
- add_offense(node, location: :name, message: message)
46
+ add_offense(node, message: message)
47
47
  end
48
48
  end
49
49
 
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # This cop checks if test cases contain any assertion calls.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # class FooTest < Minitest::Test
11
+ # def test_the_truth
12
+ # end
13
+ # end
14
+ #
15
+ # # good
16
+ # class FooTest < Minitest::Test
17
+ # def test_the_truth
18
+ # assert true
19
+ # end
20
+ # end
21
+ #
22
+ class NoAssertions < Base
23
+ include MinitestExplorationHelpers
24
+
25
+ MSG = 'Test case has no assertions.'
26
+
27
+ def on_class(class_node)
28
+ return unless test_class?(class_node)
29
+
30
+ test_cases(class_node).each do |node|
31
+ assertions_count = assertions_count(node)
32
+
33
+ next if assertions_count.positive?
34
+
35
+ add_offense(node.block_type? ? node.loc.expression : node.loc.name)
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def assertions_count(node)
42
+ base = assertion?(node) ? 1 : 0
43
+ base + node.each_child_node.sum { |c| assertions_count(c) }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # refute_empty(object)
16
16
  # refute_empty(object, 'message')
17
17
  #
18
- class RefuteEmpty < Cop
18
+ class RefuteEmpty < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :refute, target_method: :empty?
@@ -14,8 +14,9 @@ module RuboCop
14
14
  # # good
15
15
  # refute_equal("rubocop-minitest", actual)
16
16
  #
17
- class RefuteEqual < Cop
17
+ class RefuteEqual < Base
18
18
  include ArgumentRangeHelper
19
+ extend AutoCorrector
19
20
 
20
21
  MSG = 'Prefer using `refute_equal(%<preferred>s)` over ' \
21
22
  '`assert(%<over>s)`.'
@@ -29,13 +30,10 @@ module RuboCop
29
30
  preferred, over = process_not_equal(node)
30
31
  return unless preferred && over
31
32
 
32
- message = format(MSG, preferred: preferred, over: over)
33
- add_offense(node, message: message)
34
- end
33
+ assert_not_equal(node) do |_, expected, actual|
34
+ message = format(MSG, preferred: preferred, over: over)
35
35
 
36
- def autocorrect(node)
37
- lambda do |corrector|
38
- assert_not_equal(node) do |_, expected, actual|
36
+ add_offense(node, message: message) do |corrector|
39
37
  corrector.replace(node.loc.selector, 'refute_equal')
40
38
 
41
39
  replacement = [expected, actual].map(&:source).join(', ')
@@ -18,13 +18,12 @@ module RuboCop
18
18
  # refute(actual)
19
19
  # refute(actual, 'message')
20
20
  #
21
- class RefuteFalse < Cop
21
+ class RefuteFalse < Base
22
22
  include ArgumentRangeHelper
23
+ extend AutoCorrector
23
24
 
24
- MSG_FOR_ASSERT_EQUAL = 'Prefer using `refute(%<arguments>s)` over ' \
25
- '`assert_equal(false, %<arguments>s)`.'
26
- MSG_FOR_ASSERT = 'Prefer using `refute(%<arguments>s)` over ' \
27
- '`assert(!%<arguments>s)`.'
25
+ MSG_FOR_ASSERT_EQUAL = 'Prefer using `refute(%<arguments>s)` over `assert_equal(false, %<arguments>s)`.'
26
+ MSG_FOR_ASSERT = 'Prefer using `refute(%<arguments>s)` over `assert(!%<arguments>s)`.'
28
27
  RESTRICT_ON_SEND = %i[assert_equal assert].freeze
29
28
 
30
29
  def_node_matcher :assert_equal_with_false, <<~PATTERN
@@ -36,38 +35,29 @@ module RuboCop
36
35
  PATTERN
37
36
 
38
37
  def on_send(node)
39
- actual, rest_receiver_arg = assert_equal_with_false(node) ||
40
- assert_with_bang_argument(node)
38
+ actual, rest_receiver_arg = assert_equal_with_false(node) || assert_with_bang_argument(node)
41
39
  return unless actual
42
40
 
43
41
  message_argument = rest_receiver_arg.first
44
42
 
45
43
  arguments = [actual.source, message_argument&.source].compact.join(', ')
46
44
 
47
- message = if node.method?(:assert_equal)
48
- MSG_FOR_ASSERT_EQUAL
49
- else
50
- MSG_FOR_ASSERT
51
- end
45
+ message = node.method?(:assert_equal) ? MSG_FOR_ASSERT_EQUAL : MSG_FOR_ASSERT
52
46
 
53
- add_offense(node, message: format(message, arguments: arguments))
47
+ add_offense(node, message: format(message, arguments: arguments)) do |corrector|
48
+ autocorrect(corrector, node, actual)
49
+ end
54
50
  end
55
51
 
56
- def autocorrect(node)
57
- lambda do |corrector|
58
- corrector.replace(node.loc.selector, 'refute')
52
+ private
59
53
 
60
- assert_equal_with_false(node) do |actual|
61
- corrector.replace(
62
- first_and_second_arguments_range(node), actual.source
63
- )
64
- end
54
+ def autocorrect(corrector, node, actual)
55
+ corrector.replace(node.loc.selector, 'refute')
65
56
 
66
- assert_with_bang_argument(node) do |actual|
67
- corrector.replace(
68
- first_argument_range(node), actual.source
69
- )
70
- end
57
+ if node.method?(:assert_equal)
58
+ corrector.replace(first_and_second_arguments_range(node), actual.source)
59
+ else
60
+ corrector.replace(first_argument_range(node), actual.source)
71
61
  end
72
62
  end
73
63
  end
@@ -15,8 +15,9 @@ module RuboCop
15
15
  # refute_in_delta(0.2, actual)
16
16
  # refute_in_delta(0.2, actual, 0.001, 'message')
17
17
  #
18
- class RefuteInDelta < Cop
18
+ class RefuteInDelta < Base
19
19
  include InDeltaMixin
20
+ extend AutoCorrector
20
21
 
21
22
  RESTRICT_ON_SEND = %i[refute_equal].freeze
22
23
 
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # refute_includes(collection, object)
16
16
  # refute_includes(collection, object, 'message')
17
17
  #
18
- class RefuteIncludes < Cop
18
+ class RefuteIncludes < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :refute, target_method: :include?, preferred_method: :refute_includes
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # refute_instance_of(Class, object)
16
16
  # refute_instance_of(Class, object, 'message')
17
17
  #
18
- class RefuteInstanceOf < Cop
18
+ class RefuteInstanceOf < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :refute, target_method: :instance_of?, inverse: true
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # refute_kind_of(Class, object)
16
16
  # refute_kind_of(Class, object, 'message')
17
17
  #
18
- class RefuteKindOf < Cop
18
+ class RefuteKindOf < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :refute, target_method: :kind_of?, inverse: true
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # refute_match(matcher, string)
16
16
  # refute_match(matcher, string, 'message')
17
17
  #
18
- class RefuteMatch < Cop
18
+ class RefuteMatch < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :refute, target_method: :match
@@ -15,8 +15,9 @@ module RuboCop
15
15
  # refute_nil(actual)
16
16
  # refute_nil(actual, 'message')
17
17
  #
18
- class RefuteNil < Cop
18
+ class RefuteNil < Base
19
19
  include ArgumentRangeHelper
20
+ extend AutoCorrector
20
21
 
21
22
  MSG = 'Prefer using `refute_nil(%<arguments>s)` over ' \
22
23
  '`refute_equal(nil, %<arguments>s)`.'
@@ -32,13 +33,7 @@ module RuboCop
32
33
 
33
34
  arguments = [actual.source, message&.source].compact.join(', ')
34
35
 
35
- add_offense(node, message: format(MSG, arguments: arguments))
36
- end
37
- end
38
-
39
- def autocorrect(node)
40
- lambda do |corrector|
41
- refute_equal_with_nil(node) do |actual|
36
+ add_offense(node, message: format(MSG, arguments: arguments)) do |corrector|
42
37
  corrector.replace(node.loc.selector, 'refute_nil')
43
38
  corrector.replace(
44
39
  first_and_second_arguments_range(node), actual.source
@@ -15,7 +15,9 @@ module RuboCop
15
15
  # refute_path_exists(path)
16
16
  # refute_path_exists(path, 'message')
17
17
  #
18
- class RefutePathExists < Cop
18
+ class RefutePathExists < Base
19
+ extend AutoCorrector
20
+
19
21
  MSG = 'Prefer using `%<good_method>s` over `%<bad_method>s`.'
20
22
  RESTRICT_ON_SEND = %i[refute].freeze
21
23
 
@@ -32,17 +34,8 @@ module RuboCop
32
34
  good_method = build_good_method(path, failure_message)
33
35
  message = format(MSG, good_method: good_method, bad_method: node.source)
34
36
 
35
- add_offense(node, message: message)
36
- end
37
- end
38
-
39
- def autocorrect(node)
40
- refute_file_exists(node) do |path, failure_message|
41
- failure_message = failure_message.first
42
-
43
- lambda do |corrector|
44
- replacement = build_good_method(path, failure_message)
45
- corrector.replace(node, replacement)
37
+ add_offense(node, message: message) do |corrector|
38
+ corrector.replace(node, good_method)
46
39
  end
47
40
  end
48
41
  end
@@ -17,7 +17,7 @@ module RuboCop
17
17
  # refute_respond_to(object, :do_something, 'message')
18
18
  # refute_respond_to(self, :do_something)
19
19
  #
20
- class RefuteRespondTo < Cop
20
+ class RefuteRespondTo < Base
21
21
  extend MinitestCopRule
22
22
 
23
23
  define_rule :refute, target_method: :respond_to?
@@ -27,9 +27,10 @@ module RuboCop
27
27
  # end
28
28
  # end
29
29
  #
30
- class TestMethodName < Cop
30
+ class TestMethodName < Base
31
31
  include MinitestExplorationHelpers
32
32
  include DefNode
33
+ extend AutoCorrector
33
34
 
34
35
  MSG = 'Test method name should start with `test_` prefix.'
35
36
 
@@ -37,13 +38,13 @@ module RuboCop
37
38
  return unless test_class?(class_node)
38
39
 
39
40
  class_elements(class_node).each do |node|
40
- add_offense(node, location: :name) if offense?(node)
41
- end
42
- end
41
+ next unless offense?(node)
42
+
43
+ test_method_name = node.loc.name
43
44
 
44
- def autocorrect(node)
45
- lambda do |corrector|
46
- corrector.replace(node.loc.name, "test_#{node.method_name}")
45
+ add_offense(test_method_name) do |corrector|
46
+ corrector.replace(test_method_name, "test_#{node.method_name}")
47
+ end
47
48
  end
48
49
  end
49
50