rubocop-minitest 0.24.0 → 0.26.1

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: b0a695c307538885f790b2efe35af28113a4f76baf8ba870ae41d870a54b31fe
4
- data.tar.gz: 40f94eb2dfa3d962e9ffba5dc989d281ae74f81ec3cbfac442e15095ac3d612c
3
+ metadata.gz: 30d74ad78ccdb578c6cc6e19c201f1b14869fea35d42f20c951e2a3ccd9da72d
4
+ data.tar.gz: 4ebac2d4e8a5efc3b0238388769986db1ab0625812cc378f0acd907428a180df
5
5
  SHA512:
6
- metadata.gz: 04c9af1d29a613536c03c372fac160ad7df0d32e68354f765bfbb178dfcca27b670da7f55bce7923dbbc048c227346f9656b31b8f641ba07254a7bf61c2a6d10
7
- data.tar.gz: 9e3c8090307fa86ba39e2b917e583815616e4ae82bbb32d36cadcaa7f1eca3ca293d8907b71bfaa3bebf9e643fd5380040983802f624094a4f1776794c98b838
6
+ metadata.gz: a6b65afa72586fd58d096ce07858b0373cb65d9ba637807d557e7043347856e3ad69bd0fba61e1ef80fb69fb2928a4f6234200e40454ac068b85ec6579f03c36
7
+ data.tar.gz: c5d62abb9019d7b89c7c4e5b2e50cbf696e1ef6fd31323c2674648faa1f535f50e96f45778f3b17078126a74a4e324125f3ec34b054a3f44ec91288d9046e221
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2019-2022 Bozhidar Batsov, Jonas Arvidsson, Koichi ITO
3
+ Copyright (c) 2019-2023 Bozhidar Batsov, Jonas Arvidsson, Koichi ITO
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/config/default.yml CHANGED
@@ -85,7 +85,9 @@ Minitest/AssertRaisesCompoundBody:
85
85
  Minitest/AssertRaisesWithRegexpArgument:
86
86
  Description: 'This cop enforces checks for regular expression literals passed to `assert_raises`.'
87
87
  Enabled: pending
88
+ Severity: warning
88
89
  VersionAdded: '0.22'
90
+ VersionChanged: '0.26'
89
91
 
90
92
  Minitest/AssertRespondTo:
91
93
  Description: 'This cop enforces the test to use `assert_respond_to(object, :do_something)` over `assert(object.respond_to?(:do_something))`.'
@@ -93,6 +95,12 @@ Minitest/AssertRespondTo:
93
95
  Enabled: true
94
96
  VersionAdded: '0.3'
95
97
 
98
+ Minitest/AssertSame:
99
+ Description: 'Enforces the use of `assert_same(expected, actual)` over `assert(expected.equal?(actual))`.'
100
+ StyleGuide: 'https://minitest.rubystyle.guide#assert-same'
101
+ Enabled: pending
102
+ VersionAdded: '0.26'
103
+
96
104
  Minitest/AssertSilent:
97
105
  Description: "This cop enforces the test to use `assert_silent { ... }` instead of using `assert_output('', '') { ... }`."
98
106
  StyleGuide: 'https://github.com/rubocop/minitest-style-guide#assert-silent'
@@ -103,13 +111,17 @@ Minitest/AssertTruthy:
103
111
  Description: 'This cop enforces the test to use `assert(actual)` instead of using `assert_equal(true, actual)`.'
104
112
  StyleGuide: 'https://minitest.rubystyle.guide#assert-truthy'
105
113
  Enabled: true
114
+ SafeAutoCorrect: false
106
115
  VersionAdded: '0.2'
116
+ VersionChanged: '0.26'
107
117
 
108
118
  Minitest/AssertWithExpectedArgument:
109
119
  Description: 'This cop tries to detect when a user accidentally used `assert` when they meant to use `assert_equal`.'
110
120
  Enabled: pending
121
+ Severity: warning
111
122
  Safe: false
112
123
  VersionAdded: '0.11'
124
+ VersionChanged: '0.26'
113
125
 
114
126
  Minitest/AssertionInLifecycleHook:
115
127
  Description: 'This cop checks for usage of assertions in lifecycle hooks.'
@@ -131,6 +143,7 @@ Minitest/GlobalExpectations:
131
143
  Description: 'This cop checks for deprecated global expectations.'
132
144
  StyleGuide: 'https://minitest.rubystyle.guide#global-expectations'
133
145
  Enabled: true
146
+ Severity: warning
134
147
  EnforcedStyle: any
135
148
  Include:
136
149
  - '**/test/**/*'
@@ -143,7 +156,7 @@ Minitest/GlobalExpectations:
143
156
  - expect
144
157
  - value
145
158
  VersionAdded: '0.7'
146
- VersionChanged: '0.16'
159
+ VersionChanged: '0.26'
147
160
 
148
161
  Minitest/LiteralAsActualArgument:
149
162
  Description: 'This cop enforces correct order of `expected` and `actual` arguments for `assert_equal`.'
@@ -234,16 +247,30 @@ Minitest/RefuteRespondTo:
234
247
  Enabled: true
235
248
  VersionAdded: '0.4'
236
249
 
250
+ Minitest/RefuteSame:
251
+ Description: 'Enforces the use of `refute_same(expected, actual)` over `refute(expected.equal?(actual))`.'
252
+ StyleGuide: 'https://minitest.rubystyle.guide#refute-same'
253
+ Enabled: pending
254
+ VersionAdded: '0.26'
255
+
237
256
  Minitest/SkipEnsure:
238
257
  Description: 'Checks that `ensure` call even if `skip`.'
239
258
  Enabled: pending
259
+ Severity: warning
240
260
  VersionAdded: '0.20'
261
+ VersionChanged: '0.26'
241
262
 
242
263
  Minitest/SkipWithoutReason:
243
264
  Description: 'Checks for skipped tests missing the skipping reason.'
244
265
  Enabled: pending
245
266
  VersionAdded: '0.24'
246
267
 
268
+ Minitest/TestFileName:
269
+ Description: 'Checks if test file names start with `test_` or end with `_test.rb`.'
270
+ StyleGuide: 'https://minitest.rubystyle.guide/#file-naming'
271
+ Enabled: pending
272
+ VersionAdded: '0.26'
273
+
247
274
  Minitest/TestMethodName:
248
275
  Description: 'This cop enforces that test method names start with `test_` prefix.'
249
276
  Enabled: 'pending'
@@ -252,10 +279,17 @@ Minitest/TestMethodName:
252
279
  Minitest/UnreachableAssertion:
253
280
  Description: 'This cop checks for an `assert_raises` block containing any unreachable assertions.'
254
281
  Enabled: pending
282
+ Severity: warning
255
283
  VersionAdded: '0.14'
284
+ VersionChanged: '0.26'
256
285
 
257
286
  Minitest/UnspecifiedException:
258
287
  Description: 'This cop checks for a specified error in `assert_raises`.'
259
288
  StyleGuide: 'https://minitest.rubystyle.guide#unspecified-exception'
260
289
  Enabled: 'pending'
261
290
  VersionAdded: '0.10'
291
+
292
+ Minitest/UselessAssertion:
293
+ Description: 'Detects useless assertions (assertions that either always pass or always fail).'
294
+ Enabled: pending
295
+ VersionAdded: '0.26'
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # Enforces the use of `assert_same(expected, actual)`
7
+ # over `assert(expected.equal?(actual))`.
8
+ #
9
+ # NOTE: Use `assert_same` only when there is a need to compare by identity.
10
+ # Otherwise, use `assert_equal`.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # assert(expected.equal?(actual))
15
+ #
16
+ # # good
17
+ # assert_same(expected, actual)
18
+ #
19
+ class AssertSame < Base
20
+ extend MinitestCopRule
21
+
22
+ define_rule :assert, target_method: :equal?, preferred_method: :assert_same
23
+ end
24
+ end
25
+ end
26
+ end
@@ -5,6 +5,9 @@ module RuboCop
5
5
  module Minitest
6
6
  # Enforces the test to use `assert(actual)` instead of using `assert_equal(true, actual)`.
7
7
  #
8
+ # @safety
9
+ # This cop's autocorrection is unsafe because true might be expected instead of truthy.
10
+ #
8
11
  # @example
9
12
  # # bad
10
13
  # assert_equal(true, actual)
@@ -6,6 +6,9 @@ module RuboCop
6
6
  # Tries to detect when a user accidentally used
7
7
  # `assert` when they meant to use `assert_equal`.
8
8
  #
9
+ # NOTE: The second argument to the `assert` method named `message` and `msg` is allowed.
10
+ # Because their names are inferred as message arguments.
11
+ #
9
12
  # @safety
10
13
  # This cop is unsafe because it is not possible to determine
11
14
  # whether the second argument of `assert` is a message or not.
@@ -19,10 +22,13 @@ module RuboCop
19
22
  # assert_equal(3, my_list.length)
20
23
  # assert_equal(expected, actual)
21
24
  # assert(foo, 'message')
25
+ # assert(foo, message)
26
+ # assert(foo, msg)
22
27
  #
23
28
  class AssertWithExpectedArgument < Base
24
29
  MSG = 'Did you mean to use `assert_equal(%<arguments>s)`?'
25
30
  RESTRICT_ON_SEND = %i[assert].freeze
31
+ MESSAGE_VARIABLES = %w[message msg].freeze
26
32
 
27
33
  def_node_matcher :assert_with_two_arguments?, <<~PATTERN
28
34
  (send nil? :assert $_ $_)
@@ -30,7 +36,7 @@ module RuboCop
30
36
 
31
37
  def on_send(node)
32
38
  assert_with_two_arguments?(node) do |_expected, message|
33
- return if message.str_type? || message.dstr_type?
39
+ return if message.str_type? || message.dstr_type? || MESSAGE_VARIABLES.include?(message.source)
34
40
 
35
41
  arguments = node.arguments.map(&:source).join(', ')
36
42
  add_offense(node, message: format(MSG, arguments: arguments))
@@ -53,7 +53,7 @@ module RuboCop
53
53
  return true if !previous_line_node.is_a?(RuboCop::AST::Node) ||
54
54
  previous_line_node.args_type? || node.parent.basic_conditional?
55
55
 
56
- previous_line_node.send_type? && assertion_method?(previous_line_node)
56
+ assertion_method?(previous_line_node)
57
57
  end
58
58
 
59
59
  def use_heredoc_argument?(node)
@@ -50,8 +50,9 @@ module RuboCop
50
50
  private
51
51
 
52
52
  def assertions_count(node)
53
- base = assertion_method?(node) ? 1 : 0
54
- base + node.each_child_node.sum { |c| assertions_count(c) }
53
+ node.each_descendant(:send).count do |send_node|
54
+ assertion_method?(send_node)
55
+ end
55
56
  end
56
57
 
57
58
  def max_assertions
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # Enforces the use of `refute_same(expected, object)`
7
+ # over `refute(expected.equal?(actual))`.
8
+ #
9
+ # NOTE: Use `refute_same` only when there is a need to compare by identity.
10
+ # Otherwise, use `refute_equal`.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # refute(expected.equal?(actual))
15
+ #
16
+ # # good
17
+ # refute_same(expected, actual)
18
+ #
19
+ class RefuteSame < Base
20
+ extend MinitestCopRule
21
+
22
+ define_rule :refute, target_method: :equal?, preferred_method: :refute_same
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # Checks if test file names start with `test_` or end with `_test.rb`.
7
+ # Files which define classes having names ending with `Test` are checked.
8
+ # Not following this convention may result in tests not being run.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # my_class.rb
13
+ #
14
+ # # good
15
+ # my_class_test.rb
16
+ # test_my_class.rb
17
+ #
18
+ class TestFileName < Base
19
+ include MinitestExplorationHelpers
20
+
21
+ MSG = 'Test file path should start with `test_` or end with `_test.rb`.'
22
+
23
+ def on_new_investigation
24
+ return unless (ast = processed_source.ast)
25
+ return unless test_file?(ast)
26
+
27
+ add_global_offense(MSG) unless valid_file_name?
28
+ end
29
+
30
+ private
31
+
32
+ def test_file?(node)
33
+ return true if node.class_type? && test_class?(node)
34
+
35
+ node.each_descendant(:class).any? { |class_node| test_class?(class_node) }
36
+ end
37
+
38
+ def valid_file_name?
39
+ basename = File.basename(processed_source.file_path)
40
+
41
+ basename.start_with?('test_') || basename.end_with?('_test.rb')
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # Detects useless assertions (assertions that either always pass or always fail).
7
+ #
8
+ # @example
9
+ # # bad
10
+ # assert true
11
+ # assert_equal @foo, @foo
12
+ # assert_nil [foo, bar]
13
+ #
14
+ # # good
15
+ # assert something
16
+ # assert_equal foo, bar
17
+ # assert_nil foo
18
+ # assert false, "My message"
19
+ #
20
+ class UselessAssertion < Base
21
+ MSG = 'Useless assertion detected.'
22
+
23
+ SINGLE_ASSERTION_ARGUMENT_METHODS = %i[
24
+ assert refute assert_nil refute_nil assert_not assert_empty refute_empty
25
+ ].freeze
26
+ TWO_ASSERTION_ARGUMENTS_METHODS = %i[
27
+ assert_equal refute_equal assert_in_delta refute_in_delta
28
+ assert_in_epsilon refute_in_epsilon assert_same refute_same
29
+ ].freeze
30
+
31
+ RESTRICT_ON_SEND = SINGLE_ASSERTION_ARGUMENT_METHODS +
32
+ TWO_ASSERTION_ARGUMENTS_METHODS +
33
+ %i[assert_includes refute_includes assert_silent]
34
+
35
+ def on_send(node)
36
+ return if node.receiver
37
+
38
+ add_offense(node) if offense?(node)
39
+ end
40
+
41
+ private
42
+
43
+ # rubocop:disable Metrics
44
+ def offense?(node)
45
+ expected, actual, = node.arguments
46
+
47
+ case node.method_name
48
+ when *SINGLE_ASSERTION_ARGUMENT_METHODS
49
+ actual.nil? && expected&.literal?
50
+ when *TWO_ASSERTION_ARGUMENTS_METHODS
51
+ return false unless expected || actual
52
+ return false if expected.source != actual.source
53
+
54
+ (expected.variable? && actual.variable?) ||
55
+ (empty_composite?(expected) && empty_composite?(actual))
56
+ when :assert_includes, :refute_includes
57
+ expected && empty_composite?(expected)
58
+ when :assert_silent
59
+ block_node = node.parent
60
+ block_node&.body.nil?
61
+ else
62
+ false
63
+ end
64
+ end
65
+ # rubocop:enable Metrics
66
+
67
+ def empty_composite?(node)
68
+ return true if node.str_type? && node.value.empty?
69
+
70
+ (node.array_type? || node.hash_type?) && node.children.empty?
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -23,10 +23,12 @@ require_relative 'minitest/assert_match'
23
23
  require_relative 'minitest/assert_output'
24
24
  require_relative 'minitest/assert_path_exists'
25
25
  require_relative 'minitest/assert_respond_to'
26
+ require_relative 'minitest/assert_same'
26
27
  require_relative 'minitest/assert_silent'
27
28
  require_relative 'minitest/assert_truthy'
28
29
  require_relative 'minitest/duplicate_test_run'
29
30
  require_relative 'minitest/empty_line_before_assertion_methods'
31
+ require_relative 'minitest/test_file_name'
30
32
  require_relative 'minitest/global_expectations'
31
33
  require_relative 'minitest/literal_as_actual_argument'
32
34
  require_relative 'minitest/multiple_assertions'
@@ -43,8 +45,10 @@ require_relative 'minitest/refute_instance_of'
43
45
  require_relative 'minitest/refute_path_exists'
44
46
  require_relative 'minitest/refute_predicate'
45
47
  require_relative 'minitest/refute_respond_to'
48
+ require_relative 'minitest/refute_same'
46
49
  require_relative 'minitest/skip_ensure'
47
50
  require_relative 'minitest/skip_without_reason'
48
51
  require_relative 'minitest/test_method_name'
49
52
  require_relative 'minitest/unreachable_assertion'
50
53
  require_relative 'minitest/unspecified_exception'
54
+ require_relative 'minitest/useless_assertion'
@@ -38,7 +38,7 @@ module RuboCop
38
38
 
39
39
  # Support Active Support's `test 'example' { ... }` method.
40
40
  # https://api.rubyonrails.org/classes/ActiveSupport/Testing/Declarative.html
41
- test_blocks = class_node.each_descendant(:block).select { |block_node| block_node.method?(:test) }
41
+ test_blocks = class_node.each_descendant(:block).select { |block| block.method?(:test) || block.method?(:it) }
42
42
 
43
43
  test_cases + test_blocks
44
44
  end
@@ -78,7 +78,7 @@ module RuboCop
78
78
  end
79
79
 
80
80
  def assertion_method?(node)
81
- return false unless node.send_type?
81
+ return false if !node.send_type? && !node.block_type?
82
82
 
83
83
  ASSERTION_PREFIXES.any? do |prefix|
84
84
  method_name = node.method_name
@@ -70,6 +70,8 @@ module RuboCop
70
70
  # RUBY
71
71
  #
72
72
  # assert_no_corrections
73
+ #
74
+ # rubocop:disable Metrics/ModuleLength
73
75
  module AssertOffense
74
76
  private
75
77
 
@@ -79,6 +81,16 @@ module RuboCop
79
81
  @cop = RuboCop::Cop::Minitest.const_get(cop_name).new
80
82
  end
81
83
 
84
+ def format_offense(source, **replacements)
85
+ replacements.each do |keyword, value|
86
+ value = value.to_s
87
+ source = source.gsub("%{#{keyword}}", value)
88
+ .gsub("^{#{keyword}}", '^' * value.size)
89
+ .gsub("_{#{keyword}}", ' ' * value.size)
90
+ end
91
+ source
92
+ end
93
+
82
94
  def assert_no_offenses(source, file = nil)
83
95
  setup_assertion
84
96
 
@@ -90,11 +102,12 @@ module RuboCop
90
102
  assert_equal(source, actual_annotations.to_s)
91
103
  end
92
104
 
93
- def assert_offense(source, file = nil)
105
+ def assert_offense(source, file = nil, **replacements)
94
106
  setup_assertion
95
107
 
96
108
  @cop.instance_variable_get(:@options)[:autocorrect] = true
97
109
 
110
+ source = format_offense(source, **replacements)
98
111
  expected_annotations = RuboCop::RSpec::ExpectOffense::AnnotatedSource.parse(source)
99
112
  if expected_annotations.plain_source == source
100
113
  raise 'Use `assert_no_offenses` to assert that no offenses are found'
@@ -205,5 +218,6 @@ module RuboCop
205
218
  2.6
206
219
  end
207
220
  end
221
+ # rubocop:enable Metrics/ModuleLength
208
222
  end
209
223
  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.24.0'
7
+ STRING = '0.26.1'
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.24.0
4
+ version: 0.26.1
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: 2022-11-27 00:00:00.000000000 Z
13
+ date: 2023-01-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -74,6 +74,7 @@ files:
74
74
  - lib/rubocop/cop/minitest/assert_raises_compound_body.rb
75
75
  - lib/rubocop/cop/minitest/assert_raises_with_regexp_argument.rb
76
76
  - lib/rubocop/cop/minitest/assert_respond_to.rb
77
+ - lib/rubocop/cop/minitest/assert_same.rb
77
78
  - lib/rubocop/cop/minitest/assert_silent.rb
78
79
  - lib/rubocop/cop/minitest/assert_truthy.rb
79
80
  - lib/rubocop/cop/minitest/assert_with_expected_argument.rb
@@ -96,11 +97,14 @@ files:
96
97
  - lib/rubocop/cop/minitest/refute_path_exists.rb
97
98
  - lib/rubocop/cop/minitest/refute_predicate.rb
98
99
  - lib/rubocop/cop/minitest/refute_respond_to.rb
100
+ - lib/rubocop/cop/minitest/refute_same.rb
99
101
  - lib/rubocop/cop/minitest/skip_ensure.rb
100
102
  - lib/rubocop/cop/minitest/skip_without_reason.rb
103
+ - lib/rubocop/cop/minitest/test_file_name.rb
101
104
  - lib/rubocop/cop/minitest/test_method_name.rb
102
105
  - lib/rubocop/cop/minitest/unreachable_assertion.rb
103
106
  - lib/rubocop/cop/minitest/unspecified_exception.rb
107
+ - lib/rubocop/cop/minitest/useless_assertion.rb
104
108
  - lib/rubocop/cop/minitest_cops.rb
105
109
  - lib/rubocop/cop/mixin/argument_range_helper.rb
106
110
  - lib/rubocop/cop/mixin/in_delta_mixin.rb
@@ -120,7 +124,7 @@ metadata:
120
124
  homepage_uri: https://docs.rubocop.org/rubocop-minitest/
121
125
  changelog_uri: https://github.com/rubocop/rubocop-minitest/blob/master/CHANGELOG.md
122
126
  source_code_uri: https://github.com/rubocop/rubocop-minitest
123
- documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.24
127
+ documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.26
124
128
  bug_tracker_uri: https://github.com/rubocop/rubocop-minitest/issues
125
129
  rubygems_mfa_required: 'true'
126
130
  post_install_message: