rubocop-minitest 0.11.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ">="