rubocop-minitest 0.25.0 → 0.26.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49b67a4071b6ba9e1499054507097424e25948f916e3ebbcf65603d4e0806b94
4
- data.tar.gz: 46a351626a6ec6625d5e29fc0f04c47d61844bc28e2745172ea0bb8344936751
3
+ metadata.gz: 90dad8a03c65bc80912012a2dacd5e8f6dd89485c72930a6348d16f489d2a8a9
4
+ data.tar.gz: 5465e2ad38af5358f9942cf47fbeffc00abbee76dec902835d3fa67be2a678fd
5
5
  SHA512:
6
- metadata.gz: 4abcc9e3035a7e7a2902b27442f02f46a9494a2894acb5f5c98d18293d4c0d1ab94e32b2508bf1b23988cca436f7b7d4fd784dfe09fc21fae0c70ba2d6ef80ec
7
- data.tar.gz: 6d669e4ff6e60a729a64c5ea87d4f91a20022f4a47cda95a52a10f6084de258a497d66ceeb71c0c08c1e8bbf8538823ac534349ec7644c24ab35df5b8317b30f
6
+ metadata.gz: 6d330efbe33b77b6bc18263644316525831433ef9f9a6e911fc2262ae698c7a90f0cc32a5a3f0ef021cea89f96cca3c355c9573f65a0a7479fceae61db7c3bbf
7
+ data.tar.gz: 3f3487a2714c447d9b6cc97f28d8e1767835b25f2feb160bf967b86f90f77242de8d0ce07d50fc6992786112ac06ade62870e4d83887fb4c964a8cfcd9a40248
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)
@@ -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,45 @@
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 test_file?(processed_source.ast)
25
+
26
+ add_global_offense(MSG) unless valid_file_name?
27
+ end
28
+
29
+ private
30
+
31
+ def test_file?(node)
32
+ return true if node.class_type? && test_class?(node)
33
+
34
+ node.each_descendant(:class).any? { |class_node| test_class?(class_node) }
35
+ end
36
+
37
+ def valid_file_name?
38
+ basename = File.basename(processed_source.file_path)
39
+
40
+ basename.start_with?('test_') || basename.end_with?('_test.rb')
41
+ end
42
+ end
43
+ end
44
+ end
45
+ 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'
@@ -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.25.0'
7
+ STRING = '0.26.0'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-minitest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.0
4
+ version: 0.26.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: 2022-12-10 00:00:00.000000000 Z
13
+ date: 2023-01-14 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.25
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: