rubocop-minitest 0.11.1 → 0.12.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +0 -3
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +10 -0
  5. data/config/default.yml +5 -0
  6. data/docs/antora.yml +1 -1
  7. data/docs/modules/ROOT/pages/cops.adoc +1 -0
  8. data/docs/modules/ROOT/pages/cops_minitest.adoc +32 -0
  9. data/lib/rubocop/cop/minitest/assert_empty.rb +1 -1
  10. data/lib/rubocop/cop/minitest/assert_empty_literal.rb +4 -9
  11. data/lib/rubocop/cop/minitest/assert_equal.rb +1 -1
  12. data/lib/rubocop/cop/minitest/assert_in_delta.rb +2 -1
  13. data/lib/rubocop/cop/minitest/assert_includes.rb +1 -1
  14. data/lib/rubocop/cop/minitest/assert_instance_of.rb +1 -1
  15. data/lib/rubocop/cop/minitest/assert_kind_of.rb +1 -1
  16. data/lib/rubocop/cop/minitest/assert_match.rb +1 -1
  17. data/lib/rubocop/cop/minitest/assert_nil.rb +4 -11
  18. data/lib/rubocop/cop/minitest/assert_output.rb +1 -1
  19. data/lib/rubocop/cop/minitest/assert_path_exists.rb +5 -12
  20. data/lib/rubocop/cop/minitest/assert_respond_to.rb +1 -1
  21. data/lib/rubocop/cop/minitest/assert_silent.rb +8 -6
  22. data/lib/rubocop/cop/minitest/assert_truthy.rb +4 -11
  23. data/lib/rubocop/cop/minitest/assert_with_expected_argument.rb +1 -1
  24. data/lib/rubocop/cop/minitest/assertion_in_lifecycle_hook.rb +1 -1
  25. data/lib/rubocop/cop/minitest/global_expectations.rb +4 -7
  26. data/lib/rubocop/cop/minitest/literal_as_actual_argument.rb +14 -14
  27. data/lib/rubocop/cop/minitest/multiple_assertions.rb +2 -2
  28. data/lib/rubocop/cop/minitest/no_assertions.rb +48 -0
  29. data/lib/rubocop/cop/minitest/refute_empty.rb +1 -1
  30. data/lib/rubocop/cop/minitest/refute_equal.rb +5 -7
  31. data/lib/rubocop/cop/minitest/refute_false.rb +14 -22
  32. data/lib/rubocop/cop/minitest/refute_in_delta.rb +2 -1
  33. data/lib/rubocop/cop/minitest/refute_includes.rb +1 -1
  34. data/lib/rubocop/cop/minitest/refute_instance_of.rb +1 -1
  35. data/lib/rubocop/cop/minitest/refute_kind_of.rb +1 -1
  36. data/lib/rubocop/cop/minitest/refute_match.rb +1 -1
  37. data/lib/rubocop/cop/minitest/refute_nil.rb +3 -8
  38. data/lib/rubocop/cop/minitest/refute_path_exists.rb +5 -12
  39. data/lib/rubocop/cop/minitest/refute_respond_to.rb +1 -1
  40. data/lib/rubocop/cop/minitest/test_method_name.rb +8 -7
  41. data/lib/rubocop/cop/minitest/unspecified_exception.rb +1 -1
  42. data/lib/rubocop/cop/minitest_cops.rb +1 -0
  43. data/lib/rubocop/cop/mixin/in_delta_mixin.rb +5 -15
  44. data/lib/rubocop/cop/mixin/minitest_cop_rule.rb +11 -12
  45. data/lib/rubocop/cop/mixin/minitest_exploration_helpers.rb +15 -4
  46. data/lib/rubocop/minitest/version.rb +1 -1
  47. data/relnotes/v0.12.0.md +10 -0
  48. data/rubocop-minitest.gemspec +1 -1
  49. data/tasks/cops_documentation.rake +9 -11
  50. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2581fbadb9e19f8827cc513bb86e86b431295047c2f37401416793de014f1d52
4
- data.tar.gz: 8dc80007c469db266b85d99e672a47e1f7c4c245dcbc713896232afc87a97818
3
+ metadata.gz: a7a721b7443b19d1ff86922a0500d12daa296622bee5dc17ddcc2bdbf943245e
4
+ data.tar.gz: 14616b62fce87850843091ed66d9f76281a31038fcbf78bc5ea99a2b38c5b7db
5
5
  SHA512:
6
- metadata.gz: f9e6da24df8a6dbd427a26f00a09a4a14eed05fccfd6bfc8c31e9195237f999a3c822fda7ada6c64467d07f2542a981d1b7851e6bd2ab04cf4ac4c7c343bdb47
7
- data.tar.gz: debd9d0030d135360d6019e85cfdd5dd090ed50781f3c68cf4b8687f6e7ac8dc917124b866298159858fe359a1017f177b61269b310ac5aed76b8dade6577f93
6
+ metadata.gz: bb0913607602b41d7c05e9ca5228b3dcecdd44ea10a7b5adcfb407b9c78801aa3f5d160dba9f2a629f95377c3d12001b68aac3b08cd3f44fa708255247989c71
7
+ data.tar.gz: 56a97c8ff0938d66b565b3578c5c698c85188bc7130fcf3ac7955df466b5c48a0abbed8ace45af2ea2c66aaa1f2635aaad6fb02de1f294da4a710e983aec1b94
data/.circleci/config.yml CHANGED
@@ -38,9 +38,6 @@ workflows:
38
38
  build:
39
39
  jobs:
40
40
  - documentation-checks
41
- - rake_default:
42
- name: Ruby 2.4
43
- image: circleci/ruby:2.4
44
41
  - rake_default:
45
42
  name: Ruby 2.5
46
43
  image: circleci/ruby:2.5
data/.rubocop.yml CHANGED
@@ -9,7 +9,7 @@ require:
9
9
 
10
10
  AllCops:
11
11
  NewCops: enable
12
- TargetRubyVersion: 2.4
12
+ TargetRubyVersion: 2.5
13
13
  SuggestExtensions: false
14
14
 
15
15
  InternalAffairs/NodeMatcherDirective:
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## master (unreleased)
4
4
 
5
+ ## 0.12.0 (2021-04-23)
6
+
7
+ ### New features
8
+
9
+ * [#124](https://github.com/rubocop/rubocop-minitest/pull/124): Add new `Minitest/NoAssertions` cop. ([@ghiculescu][])
10
+
11
+ ### Changes
12
+
13
+ * [#129](https://github.com/rubocop/rubocop-minitest/pull/129): Drop Ruby 2.4 support. ([@koic][])
14
+
5
15
  ## 0.11.1 (2021-03-31)
6
16
 
7
17
  ### Changes
data/config/default.yml CHANGED
@@ -118,6 +118,11 @@ Minitest/MultipleAssertions:
118
118
  VersionAdded: '0.10'
119
119
  Max: 3
120
120
 
121
+ Minitest/NoAssertions:
122
+ Description: 'This cop checks for at least one assertion (or flunk) in tests.'
123
+ Enabled: false
124
+ VersionAdded: '0.12'
125
+
121
126
  Minitest/RefuteEmpty:
122
127
  Description: 'This cop enforces to use `refute_empty` instead of using `refute(object.empty?)`.'
123
128
  StyleGuide: 'https://minitest.rubystyle.guide#refute-empty'
data/docs/antora.yml CHANGED
@@ -2,6 +2,6 @@ name: rubocop-minitest
2
2
  title: RuboCop Minitest
3
3
  # We always provide version without patch here (e.g. 1.1),
4
4
  # as patch versions should not appear in the docs.
5
- version: '0.11'
5
+ version: '0.12'
6
6
  nav:
7
7
  - modules/ROOT/nav.adoc
@@ -32,6 +32,7 @@ based on the https://minitest.rubystyle.guide/[Minitest Style Guide].
32
32
  * xref:cops_minitest.adoc#minitestglobalexpectations[Minitest/GlobalExpectations]
33
33
  * xref:cops_minitest.adoc#minitestliteralasactualargument[Minitest/LiteralAsActualArgument]
34
34
  * xref:cops_minitest.adoc#minitestmultipleassertions[Minitest/MultipleAssertions]
35
+ * xref:cops_minitest.adoc#minitestnoassertions[Minitest/NoAssertions]
35
36
  * xref:cops_minitest.adoc#minitestrefuteempty[Minitest/RefuteEmpty]
36
37
  * xref:cops_minitest.adoc#minitestrefuteequal[Minitest/RefuteEqual]
37
38
  * xref:cops_minitest.adoc#minitestrefutefalse[Minitest/RefuteFalse]
@@ -625,6 +625,38 @@ end
625
625
  | Integer
626
626
  |===
627
627
 
628
+ == Minitest/NoAssertions
629
+
630
+ |===
631
+ | Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
632
+
633
+ | Disabled
634
+ | Yes
635
+ | No
636
+ | 0.12
637
+ | -
638
+ |===
639
+
640
+ This cop checks if test cases contain any assertion calls.
641
+
642
+ === Examples
643
+
644
+ [source,ruby]
645
+ ----
646
+ # bad
647
+ class FooTest < Minitest::Test
648
+ def test_the_truth
649
+ end
650
+ end
651
+
652
+ # good
653
+ class FooTest < Minitest::Test
654
+ def test_the_truth
655
+ assert true
656
+ end
657
+ end
658
+ ----
659
+
628
660
  == Minitest/RefuteEmpty
629
661
 
630
662
  |===
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # assert_empty(object)
16
16
  # assert_empty(object, 'message')
17
17
  #
18
- class AssertEmpty < Cop
18
+ class AssertEmpty < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :assert, target_method: :empty?
@@ -14,8 +14,9 @@ module RuboCop
14
14
  # # good
15
15
  # assert_empty(object)
16
16
  #
17
- class AssertEmptyLiteral < Cop
17
+ class AssertEmptyLiteral < Base
18
18
  include ArgumentRangeHelper
19
+ extend AutoCorrector
19
20
 
20
21
  MSG = 'Prefer using `assert_empty(%<arguments>s)` over ' \
21
22
  '`assert_equal(%<literal>s, %<arguments>s)`.'
@@ -32,15 +33,9 @@ module RuboCop
32
33
  args = matchers.map(&:source).join(', ')
33
34
 
34
35
  message = format(MSG, literal: literal.source, arguments: args)
35
- add_offense(node, message: message)
36
- end
37
- end
38
-
39
- def autocorrect(node)
40
- assert_equal_with_empty_literal(node) do |_literal, matchers|
41
- object = matchers.first
36
+ add_offense(node, message: message) do |corrector|
37
+ object = matchers.first
42
38
 
43
- lambda do |corrector|
44
39
  corrector.replace(node.loc.selector, 'assert_empty')
45
40
  corrector.replace(first_and_second_arguments_range(node), object.source)
46
41
  end
@@ -13,7 +13,7 @@ module RuboCop
13
13
  # # good
14
14
  # assert_equal("rubocop-minitest", actual)
15
15
  #
16
- class AssertEqual < Cop
16
+ class AssertEqual < Base
17
17
  extend MinitestCopRule
18
18
 
19
19
  define_rule :assert, target_method: :==, preferred_method: :assert_equal
@@ -15,8 +15,9 @@ module RuboCop
15
15
  # assert_in_delta(0.2, actual)
16
16
  # assert_in_delta(0.2, actual, 0.001, 'message')
17
17
  #
18
- class AssertInDelta < Cop
18
+ class AssertInDelta < Base
19
19
  include InDeltaMixin
20
+ extend AutoCorrector
20
21
 
21
22
  RESTRICT_ON_SEND = %i[assert_equal].freeze
22
23
 
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # assert_includes(collection, object)
16
16
  # assert_includes(collection, object, 'message')
17
17
  #
18
- class AssertIncludes < Cop
18
+ class AssertIncludes < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :assert, target_method: :include?, preferred_method: :assert_includes
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # assert_instance_of(Class, object)
16
16
  # assert_instance_of(Class, object, 'message')
17
17
  #
18
- class AssertInstanceOf < Cop
18
+ class AssertInstanceOf < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :assert, target_method: :instance_of?, inverse: true
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # assert_kind_of(Class, object)
16
16
  # assert_kind_of(Class, object, 'message')
17
17
  #
18
- class AssertKindOf < Cop
18
+ class AssertKindOf < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :assert, target_method: :kind_of?, inverse: true
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # assert_match(regex, string)
16
16
  # assert_match(matcher, string, 'message')
17
17
  #
18
- class AssertMatch < Cop
18
+ class AssertMatch < Base
19
19
  extend MinitestCopRule
20
20
 
21
21
  define_rule :assert, target_method: :match
@@ -15,8 +15,9 @@ module RuboCop
15
15
  # assert_nil(actual)
16
16
  # assert_nil(actual, 'message')
17
17
  #
18
- class AssertNil < Cop
18
+ class AssertNil < Base
19
19
  include ArgumentRangeHelper
20
+ extend AutoCorrector
20
21
 
21
22
  MSG = 'Prefer using `assert_nil(%<arguments>s)` over ' \
22
23
  '`assert_equal(nil, %<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_nil(node) do |actual|
36
+ add_offense(node, message: format(MSG, arguments: arguments)) do |corrector|
42
37
  corrector.replace(node.loc.selector, 'assert_nil')
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
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # # good
16
16
  # assert_output(expected) { puts object.method }
17
17
  #
18
- class AssertOutput < Cop
18
+ class AssertOutput < Base
19
19
  include MinitestExplorationHelpers
20
20
 
21
21
  MSG = 'Use `assert_output` instead of mutating %<name>s.'
@@ -15,7 +15,9 @@ module RuboCop
15
15
  # assert_path_exists(path)
16
16
  # assert_path_exists(path, 'message')
17
17
  #
18
- class AssertPathExists < Cop
18
+ class AssertPathExists < Base
19
+ extend AutoCorrector
20
+
19
21
  MSG = 'Prefer using `%<good_method>s` over `%<bad_method>s`.'
20
22
  RESTRICT_ON_SEND = %i[assert].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
- assert_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
  # assert_respond_to(object, :do_something, 'message')
18
18
  # assert_respond_to(self, :do_something)
19
19
  #
20
- class AssertRespondTo < Cop
20
+ class AssertRespondTo < Base
21
21
  extend MinitestCopRule
22
22
 
23
23
  define_rule :assert, target_method: :respond_to?
@@ -13,7 +13,9 @@ module RuboCop
13
13
  # # good
14
14
  # assert_silent { puts object.do_something }
15
15
  #
16
- class AssertSilent < Cop
16
+ class AssertSilent < Base
17
+ extend AutoCorrector
18
+
17
19
  MSG = 'Prefer using `assert_silent` over `assert_output("", "")`.'
18
20
 
19
21
  def_node_matcher :assert_silent_candidate?, <<~PATTERN
@@ -25,12 +27,12 @@ module RuboCop
25
27
  PATTERN
26
28
 
27
29
  def on_block(node)
28
- add_offense(node.send_node) if assert_silent_candidate?(node)
29
- end
30
+ return unless assert_silent_candidate?(node)
31
+
32
+ send_node = node.send_node
30
33
 
31
- def autocorrect(node)
32
- lambda do |corrector|
33
- corrector.replace(node, 'assert_silent')
34
+ add_offense(send_node) do |corrector|
35
+ corrector.replace(send_node, 'assert_silent')
34
36
  end
35
37
  end
36
38
 
@@ -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
@@ -19,7 +19,7 @@ module RuboCop
19
19
  # assert_equal(expected, actual)
20
20
  # assert(foo, 'message')
21
21
  #
22
- class AssertWithExpectedArgument < Cop
22
+ class AssertWithExpectedArgument < Base
23
23
  MSG = 'Did you mean to use `assert_equal(%<arguments>s)`?'
24
24
  RESTRICT_ON_SEND = %i[assert].freeze
25
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.loc.name, 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,8 +18,9 @@ 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
25
  MSG_FOR_ASSERT_EQUAL = 'Prefer using `refute(%<arguments>s)` over ' \
25
26
  '`assert_equal(false, %<arguments>s)`.'
@@ -36,38 +37,29 @@ module RuboCop
36
37
  PATTERN
37
38
 
38
39
  def on_send(node)
39
- actual, rest_receiver_arg = assert_equal_with_false(node) ||
40
- assert_with_bang_argument(node)
40
+ actual, rest_receiver_arg = assert_equal_with_false(node) || assert_with_bang_argument(node)
41
41
  return unless actual
42
42
 
43
43
  message_argument = rest_receiver_arg.first
44
44
 
45
45
  arguments = [actual.source, message_argument&.source].compact.join(', ')
46
46
 
47
- message = if node.method?(:assert_equal)
48
- MSG_FOR_ASSERT_EQUAL
49
- else
50
- MSG_FOR_ASSERT
51
- end
47
+ message = node.method?(:assert_equal) ? MSG_FOR_ASSERT_EQUAL : MSG_FOR_ASSERT
52
48
 
53
- add_offense(node, message: format(message, arguments: arguments))
49
+ add_offense(node, message: format(message, arguments: arguments)) do |corrector|
50
+ autocorrect(corrector, node, actual)
51
+ end
54
52
  end
55
53
 
56
- def autocorrect(node)
57
- lambda do |corrector|
58
- corrector.replace(node.loc.selector, 'refute')
54
+ private
59
55
 
60
- assert_equal_with_false(node) do |actual|
61
- corrector.replace(
62
- first_and_second_arguments_range(node), actual.source
63
- )
64
- end
56
+ def autocorrect(corrector, node, actual)
57
+ corrector.replace(node.loc.selector, 'refute')
65
58
 
66
- assert_with_bang_argument(node) do |actual|
67
- corrector.replace(
68
- first_argument_range(node), actual.source
69
- )
70
- end
59
+ if node.method?(:assert_equal)
60
+ corrector.replace(first_and_second_arguments_range(node), actual.source)
61
+ else
62
+ corrector.replace(first_argument_range(node), actual.source)
71
63
  end
72
64
  end
73
65
  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
 
@@ -14,7 +14,7 @@ module RuboCop
14
14
  # assert_raises(FooException) { raise FooException }
15
15
  # assert_raises(FooException, 'This should have raised') { raise FooException }
16
16
  #
17
- class UnspecifiedException < Cop
17
+ class UnspecifiedException < Base
18
18
  MSG = 'Specify the exception being captured.'
19
19
 
20
20
  def on_block(block_node)
@@ -23,6 +23,7 @@ require_relative 'minitest/assert_truthy'
23
23
  require_relative 'minitest/global_expectations'
24
24
  require_relative 'minitest/literal_as_actual_argument'
25
25
  require_relative 'minitest/multiple_assertions'
26
+ require_relative 'minitest/no_assertions'
26
27
  require_relative 'minitest/refute_empty'
27
28
  require_relative 'minitest/refute_false'
28
29
  require_relative 'minitest/refute_equal'
@@ -9,24 +9,14 @@ module RuboCop
9
9
  def on_send(node)
10
10
  equal_floats_call(node) do |expected, actual, message|
11
11
  message = message.first
12
+ good_method = build_good_method(expected, actual, message)
12
13
 
13
14
  if expected.float_type? || actual.float_type?
14
- message = format(MSG,
15
- good_method: build_good_method(expected, actual, message),
16
- bad_method: node.source)
15
+ message = format(MSG, good_method: good_method, bad_method: node.source)
17
16
 
18
- add_offense(node, message: message)
19
- end
20
- end
21
- end
22
-
23
- def autocorrect(node)
24
- equal_floats_call(node) do |expected, actual, message|
25
- message = message.first
26
- replacement = build_good_method(expected, actual, message)
27
-
28
- lambda do |corrector|
29
- corrector.replace(node, replacement)
17
+ add_offense(node, message: message) do |corrector|
18
+ corrector.replace(node, good_method)
19
+ end
30
20
  end
31
21
  end
32
22
  end
@@ -26,6 +26,7 @@ module RuboCop
26
26
 
27
27
  class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
28
28
  include ArgumentRangeHelper
29
+ extend AutoCorrector
29
30
 
30
31
  MSG = 'Prefer using `#{preferred_method}(%<new_arguments>s)` over ' \
31
32
  '`#{assertion_method}(%<original_arguments>s)`.'
@@ -36,23 +37,21 @@ module RuboCop
36
37
  return unless (arguments = peel_redundant_parentheses_from(node.arguments))
37
38
  return unless arguments.first.respond_to?(:method?) && arguments.first.method?(:#{target_method})
38
39
 
39
- add_offense(node, message: offense_message(arguments))
40
+ add_offense(node, message: offense_message(arguments)) do |corrector|
41
+ autocorrect(corrector, node, arguments)
42
+ end
40
43
  end
41
44
 
42
- def autocorrect(node)
43
- lambda do |corrector|
44
- corrector.replace(node.loc.selector, '#{preferred_method}')
45
-
46
- arguments = peel_redundant_parentheses_from(node.arguments)
45
+ def autocorrect(corrector, node, arguments)
46
+ corrector.replace(node.loc.selector, '#{preferred_method}')
47
47
 
48
- new_arguments = new_arguments(arguments).join(', ')
48
+ new_arguments = new_arguments(arguments).join(', ')
49
49
 
50
- if enclosed_in_redundant_parentheses?(node)
51
- new_arguments = '(' + new_arguments + ')'
52
- end
53
-
54
- corrector.replace(first_argument_range(node), new_arguments)
50
+ if enclosed_in_redundant_parentheses?(node)
51
+ new_arguments = '(' + new_arguments + ')'
55
52
  end
53
+
54
+ corrector.replace(first_argument_range(node), new_arguments)
56
55
  end
57
56
 
58
57
  private
@@ -19,6 +19,8 @@ module RuboCop
19
19
  refute_respond_to refute_same
20
20
  ].freeze
21
21
 
22
+ FLUNK = 'flunk'
23
+
22
24
  LIFECYCLE_HOOK_METHODS = %i[
23
25
  before_setup
24
26
  setup
@@ -42,8 +44,8 @@ module RuboCop
42
44
  end
43
45
 
44
46
  def test_cases(class_node)
45
- class_def_nodes(class_node)
46
- .select { |def_node| test_case_name?(def_node.method_name) }
47
+ (class_def_nodes(class_node).select { |def_node| test_case_name?(def_node.method_name) }) +
48
+ test_method_calls(class_node)
47
49
  end
48
50
 
49
51
  def lifecycle_hooks(class_node)
@@ -62,6 +64,12 @@ module RuboCop
62
64
  end
63
65
  end
64
66
 
67
+ # support https://api.rubyonrails.org/classes/ActiveSupport/Testing/Declarative.html
68
+ def test_method_calls(class_node)
69
+ block_nodes = class_node.each_descendant(:block)
70
+ block_nodes.select { |block_node| block_node.method?(:test) }
71
+ end
72
+
65
73
  def test_case_name?(name)
66
74
  name.to_s.start_with?('test_')
67
75
  end
@@ -82,11 +90,14 @@ module RuboCop
82
90
 
83
91
  def assertion?(node)
84
92
  node.send_type? &&
85
- ASSERTION_PREFIXES.any? { |prefix| node.method_name.to_s.start_with?(prefix) }
93
+ ASSERTION_PREFIXES.any? do |prefix|
94
+ method_name = node.method_name.to_s
95
+ method_name == FLUNK || method_name.start_with?(prefix)
96
+ end
86
97
  end
87
98
 
88
99
  def assertion_method?(method_name)
89
- ASSERTION_METHODS.include?(method_name)
100
+ method_name == FLUNK || ASSERTION_METHODS.include?(method_name)
90
101
  end
91
102
 
92
103
  def lifecycle_hook_method?(node)
@@ -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.11.1'
7
+ STRING = '0.12.0'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
@@ -0,0 +1,10 @@
1
+ ### New features
2
+
3
+ * [#124](https://github.com/rubocop/rubocop-minitest/pull/124): Add new `Minitest/NoAssertions` cop. ([@ghiculescu][])
4
+
5
+ ### Changes
6
+
7
+ * [#129](https://github.com/rubocop/rubocop-minitest/pull/129): Drop Ruby 2.4 support. ([@koic][])
8
+
9
+ [@ghiculescu]: https://github.com/ghiculescu
10
+ [@koic]: https://github.com/koic
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  DESCRIPTION
17
17
  spec.license = 'MIT'
18
18
 
19
- spec.required_ruby_version = '>= 2.4.0'
19
+ spec.required_ruby_version = '>= 2.5.0'
20
20
  spec.metadata = {
21
21
  'homepage_uri' => 'https://docs.rubocop.org/rubocop-minitest/',
22
22
  'changelog_uri' => 'https://github.com/rubocop/rubocop-minitest/blob/master/CHANGELOG.md',
@@ -46,17 +46,15 @@ task documentation_syntax_check: :yard_for_generate_documentation do
46
46
  end
47
47
 
48
48
  examples.to_a.each do |example|
49
- begin
50
- buffer = Parser::Source::Buffer.new('<code>', 1)
51
- buffer.source = example.text
52
- parser = Parser::Ruby25.new(RuboCop::AST::Builder.new)
53
- parser.diagnostics.all_errors_are_fatal = true
54
- parser.parse(buffer)
55
- rescue Parser::SyntaxError => e
56
- path = example.object.file
57
- puts "#{path}: Syntax Error in an example. #{e}"
58
- ok = false
59
- end
49
+ buffer = Parser::Source::Buffer.new('<code>', 1)
50
+ buffer.source = example.text
51
+ parser = Parser::Ruby25.new(RuboCop::AST::Builder.new)
52
+ parser.diagnostics.all_errors_are_fatal = true
53
+ parser.parse(buffer)
54
+ rescue Parser::SyntaxError => e
55
+ path = example.object.file
56
+ puts "#{path}: Syntax Error in an example. #{e}"
57
+ ok = false
60
58
  end
61
59
  end
62
60
  abort unless ok
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.11.1
4
+ version: 0.12.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: 2021-03-30 00:00:00.000000000 Z
13
+ date: 2021-04-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -105,6 +105,7 @@ files:
105
105
  - lib/rubocop/cop/minitest/global_expectations.rb
106
106
  - lib/rubocop/cop/minitest/literal_as_actual_argument.rb
107
107
  - lib/rubocop/cop/minitest/multiple_assertions.rb
108
+ - lib/rubocop/cop/minitest/no_assertions.rb
108
109
  - lib/rubocop/cop/minitest/refute_empty.rb
109
110
  - lib/rubocop/cop/minitest/refute_equal.rb
110
111
  - lib/rubocop/cop/minitest/refute_false.rb
@@ -135,6 +136,7 @@ files:
135
136
  - relnotes/v0.10.3.md
136
137
  - relnotes/v0.11.0.md
137
138
  - relnotes/v0.11.1.md
139
+ - relnotes/v0.12.0.md
138
140
  - relnotes/v0.2.0.md
139
141
  - relnotes/v0.2.1.md
140
142
  - relnotes/v0.3.0.md
@@ -159,7 +161,7 @@ metadata:
159
161
  homepage_uri: https://docs.rubocop.org/rubocop-minitest/
160
162
  changelog_uri: https://github.com/rubocop/rubocop-minitest/blob/master/CHANGELOG.md
161
163
  source_code_uri: https://github.com/rubocop/rubocop-minitest
162
- documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.11
164
+ documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.12
163
165
  bug_tracker_uri: https://github.com/rubocop/rubocop-minitest/issues
164
166
  post_install_message:
165
167
  rdoc_options: []
@@ -169,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
171
  requirements:
170
172
  - - ">="
171
173
  - !ruby/object:Gem::Version
172
- version: 2.4.0
174
+ version: 2.5.0
173
175
  required_rubygems_version: !ruby/object:Gem::Requirement
174
176
  requirements:
175
177
  - - ">="