rubocop-minitest 0.27.0 → 0.29.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: 7e4abf180bb13a43bdb76c4c4e376c9d156dc4e48f3bce9b4171a2432bceda9b
4
- data.tar.gz: '083ae2d51b7dafed513e7372eab667f9deea384676e0748af92d49c629ca9efe'
3
+ metadata.gz: 938714064905717403a5e63e0cfcca49356b3240c85f2fc26247faefa08ff65f
4
+ data.tar.gz: 2db37113c89cc16952a020d3a42f4cf3b94ee067b85b3460c0ef9786c69fe338
5
5
  SHA512:
6
- metadata.gz: 562f5efee32059aa022c9a742745a89a752ad7d74f136f17b54f84a21f9d6a0030e905c8a00ab09782274f1c1544134bc6d8d6cb0d03e7e2de70b65dcb9309a3
7
- data.tar.gz: 32d58f40bb69b87ed83ff3c342e255de7afaba760330f345d09b987ce352161577a9ee8f16677a2172cc59b48006efecb6272e71e90318281143fffe3155654b
6
+ metadata.gz: c9322ed01a4e6598b65742584421c1e92609d8340e6e077df7eb4126abdf842e646ff33a7ae6577ab1649bc2a9ab212645d607fe3db467596a0e8d61517f823e
7
+ data.tar.gz: bd62a8d102301b4898ab9c23696b8159bb0ba4c3257d37c7e91ba70263d72bf887cfb257e6e0fa060101305f011cf707d47fa69c82e9b1ce4701a47252ab7b35
data/config/default.yml CHANGED
@@ -158,6 +158,12 @@ Minitest/GlobalExpectations:
158
158
  VersionAdded: '0.7'
159
159
  VersionChanged: '0.26'
160
160
 
161
+ Minitest/LifecycleHooksOrder:
162
+ Description: 'Checks that lifecycle hooks are declared in the order in which they will be executed.'
163
+ StyleGuide: 'https://minitest.rubystyle.guide/#hooks-ordering'
164
+ Enabled: pending
165
+ VersionAdded: '0.28'
166
+
161
167
  Minitest/LiteralAsActualArgument:
162
168
  Description: 'This cop enforces correct order of `expected` and `actual` arguments for `assert_equal`.'
163
169
  StyleGuide: 'https://minitest.rubystyle.guide/#assert-equal-arguments-order'
@@ -10,7 +10,7 @@ module RuboCop
10
10
  TEST_TEMPLATE = <<~TEST
11
11
  # frozen_string_literal: true
12
12
 
13
- require 'test_helper'
13
+ require_relative '../../../test_helper'
14
14
 
15
15
  class %<cop_name>sTest < Minitest::Test
16
16
  def test_registers_offense_when_using_bad_method
@@ -9,6 +9,8 @@ module RuboCop
9
9
  # @example
10
10
  # # bad
11
11
  # assert(matcher.match(string))
12
+ # assert(matcher.match?(string))
13
+ # assert(matcher =~ string)
12
14
  # assert(matcher.match(string), 'message')
13
15
  #
14
16
  # # good
@@ -18,7 +20,8 @@ module RuboCop
18
20
  class AssertMatch < Base
19
21
  extend MinitestCopRule
20
22
 
21
- define_rule :assert, target_method: :match, inverse: 'regexp_type?'
23
+ define_rule :assert, target_method: %i[match match? =~],
24
+ preferred_method: :assert_match, inverse: 'regexp_type?'
22
25
  end
23
26
  end
24
27
  end
@@ -36,8 +36,7 @@ module RuboCop
36
36
  private
37
37
 
38
38
  def find_test_case(node)
39
- def_ancestor = node.each_ancestor(:def).first
40
- def_ancestor if test_case?(def_ancestor)
39
+ node.each_ancestor.find { |ancestor| test_case?(ancestor) }
41
40
  end
42
41
 
43
42
  def references_gvar?(assertion, gvar_name)
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # Checks that lifecycle hooks are declared in the order in which they will be executed.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # class FooTest < Minitest::Test
11
+ # def teardown; end
12
+ # def setup; end
13
+ # end
14
+ #
15
+ # # good
16
+ # class FooTest < Minitest::Test
17
+ # def setup; end
18
+ # def teardown; end
19
+ # end
20
+ #
21
+ # # bad (after test cases)
22
+ # class FooTest < Minitest::Test
23
+ # def test_something
24
+ # assert foo
25
+ # end
26
+ # def setup; end
27
+ # def teardown; end
28
+ # end
29
+ #
30
+ # # good
31
+ # class FooTest < Minitest::Test
32
+ # def setup; end
33
+ # def teardown; end
34
+ # def test_something
35
+ # assert foo
36
+ # end
37
+ # end
38
+ #
39
+ # # good (after non test case methods)
40
+ # class FooTest < Minitest::Test
41
+ # def do_something; end
42
+ # def setup; end
43
+ # def teardown; end
44
+ # end
45
+ #
46
+ class LifecycleHooksOrder < Base
47
+ include MinitestExplorationHelpers
48
+ include RangeHelp
49
+ extend AutoCorrector
50
+
51
+ MSG = '`%<current>s` is supposed to appear before `%<previous>s`.'
52
+
53
+ # Regular method's position should be last.
54
+ REGULAR_METHOD_POSITION = LIFECYCLE_HOOK_METHODS_IN_ORDER.size + 1
55
+ HOOKS_ORDER_MAP = Hash.new do |hash, hook|
56
+ hash[hook] = LIFECYCLE_HOOK_METHODS_IN_ORDER.index(hook) || REGULAR_METHOD_POSITION
57
+ end
58
+
59
+ # rubocop:disable Metrics/MethodLength
60
+ def on_class(class_node)
61
+ return unless test_class?(class_node)
62
+
63
+ previous_index = -1
64
+ previous_hook_node = nil
65
+
66
+ hooks_and_test_cases(class_node).each do |node|
67
+ hook = node.method_name
68
+ index = HOOKS_ORDER_MAP[hook]
69
+
70
+ if index < previous_index
71
+ message = format(MSG, current: hook, previous: previous_hook_node.method_name)
72
+ add_offense(node, message: message) do |corrector|
73
+ autocorrect(corrector, previous_hook_node, node)
74
+ end
75
+ end
76
+ previous_index = index
77
+ previous_hook_node = node
78
+ end
79
+ end
80
+ # rubocop:enable Metrics/MethodLength
81
+
82
+ private
83
+
84
+ def hooks_and_test_cases(class_node)
85
+ class_def_nodes(class_node).select do |node|
86
+ lifecycle_hook_method?(node) || test_case?(node)
87
+ end
88
+ end
89
+
90
+ def autocorrect(corrector, previous_node, node)
91
+ previous_node_range = range_with_comments_and_lines(previous_node)
92
+ node_range = range_with_comments_and_lines(node)
93
+
94
+ corrector.insert_before(previous_node_range, node_range.source)
95
+ corrector.remove(node_range)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -32,7 +32,7 @@ module RuboCop
32
32
 
33
33
  next if assertions_count.positive?
34
34
 
35
- add_offense(node.block_type? ? node.loc.expression : node.loc.name)
35
+ add_offense(node.block_type? ? node.source_range : node.loc.name)
36
36
  end
37
37
  end
38
38
  end
@@ -9,6 +9,8 @@ module RuboCop
9
9
  # @example
10
10
  # # bad
11
11
  # refute(matcher.match(string))
12
+ # refute(matcher.match?(string))
13
+ # refute(matcher =~ string)
12
14
  # refute(matcher.match(string), 'message')
13
15
  #
14
16
  # # good
@@ -18,7 +20,8 @@ module RuboCop
18
20
  class RefuteMatch < Base
19
21
  extend MinitestCopRule
20
22
 
21
- define_rule :refute, target_method: :match, inverse: 'regexp_type?'
23
+ define_rule :refute, target_method: %i[match match? =~],
24
+ preferred_method: :refute_match, inverse: 'regexp_type?'
22
25
  end
23
26
  end
24
27
  end
@@ -30,6 +30,7 @@ require_relative 'minitest/duplicate_test_run'
30
30
  require_relative 'minitest/empty_line_before_assertion_methods'
31
31
  require_relative 'minitest/test_file_name'
32
32
  require_relative 'minitest/global_expectations'
33
+ require_relative 'minitest/lifecycle_hooks_order'
33
34
  require_relative 'minitest/literal_as_actual_argument'
34
35
  require_relative 'minitest/multiple_assertions'
35
36
  require_relative 'minitest/no_assertions'
@@ -13,9 +13,14 @@ module RuboCop
13
13
  # define_rule :assert, target_method: :include?, preferred_method: :assert_includes
14
14
  # define_rule :assert, target_method: :instance_of?, inverse: true
15
15
  #
16
+ # @example Multiple target methods
17
+ # # `preferred_method` is required
18
+ # define_rule :assert, target_method: %i[match match? =~],
19
+ # preferred_method: :assert_match, inverse: 'regexp_type?'
20
+ #
16
21
  # @param assertion_method [Symbol] Assertion method like `assert` or `refute`.
17
- # @param target_method [Symbol] Method name offensed by assertion method arguments.
18
- # @param preferred_method [Symbol] An optional param. Custom method name replaced by
22
+ # @param target_method [Symbol, Array<Symbol>] Method name(s) offensed by assertion method arguments.
23
+ # @param preferred_method [Symbol] Is required if passing multiple target methods. Custom method name replaced by
19
24
  # autocorrection. The preferred method name that connects
20
25
  # `assertion_method` and `target_method` with `_` is
21
26
  # the default name.
@@ -24,7 +29,12 @@ module RuboCop
24
29
  # @api private
25
30
  #
26
31
  def define_rule(assertion_method, target_method:, preferred_method: nil, inverse: false)
27
- preferred_method = "#{assertion_method}_#{target_method.to_s.delete('?')}" if preferred_method.nil?
32
+ target_methods = Array(target_method)
33
+ if target_methods.size > 1 && preferred_method.nil?
34
+ raise ArgumentError, '`:preferred_method` keyword argument must be used if using more than one target method.'
35
+ end
36
+
37
+ preferred_method = "#{assertion_method}_#{target_methods.first.to_s.delete('?')}" if preferred_method.nil?
28
38
 
29
39
  class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
30
40
  include ArgumentRangeHelper
@@ -37,7 +47,8 @@ module RuboCop
37
47
  return unless node.method?(:#{assertion_method})
38
48
  return unless (arguments = peel_redundant_parentheses_from(node.arguments))
39
49
  return unless arguments.first&.call_type?
40
- return if arguments.first.arguments.empty? || !arguments.first.method?(:#{target_method})
50
+ return if arguments.first.arguments.empty? ||
51
+ #{target_methods}.none? { |target_method| arguments.first.method?(target_method) }
41
52
 
42
53
  add_offense(node, message: offense_message(arguments)) do |corrector|
43
54
  autocorrect(corrector, node, arguments)
@@ -12,14 +12,16 @@ module RuboCop
12
12
 
13
13
  ASSERTION_PREFIXES = %w[assert refute].freeze
14
14
 
15
- LIFECYCLE_HOOK_METHODS = %i[
15
+ LIFECYCLE_HOOK_METHODS_IN_ORDER = %i[
16
16
  before_setup
17
17
  setup
18
18
  after_setup
19
19
  before_teardown
20
20
  teardown
21
21
  after_teardown
22
- ].to_set.freeze
22
+ ].freeze
23
+
24
+ LIFECYCLE_HOOK_METHODS = LIFECYCLE_HOOK_METHODS_IN_ORDER.to_set.freeze
23
25
 
24
26
  private
25
27
 
@@ -28,22 +30,23 @@ module RuboCop
28
30
  end
29
31
 
30
32
  def test_case?(node)
31
- return false unless node&.def_type? && test_method?(node)
33
+ return false unless (node&.def_type? && test_method?(node)) ||
34
+ (node&.block_type? && test_block?(node))
32
35
 
33
36
  class_ancestor = node.each_ancestor(:class).first
34
37
  test_class?(class_ancestor)
35
38
  end
36
39
 
37
40
  def test_cases(class_node, visibility_check: true)
38
- test_cases = class_def_nodes(class_node).select do |def_node|
41
+ test_methods = class_def_nodes(class_node).select do |def_node|
39
42
  test_method?(def_node, visibility_check: visibility_check)
40
43
  end
41
44
 
42
45
  # Support Active Support's `test 'example' { ... }` method.
43
46
  # https://api.rubyonrails.org/classes/ActiveSupport/Testing/Declarative.html
44
- test_blocks = class_node.each_descendant(:block).select { |block| block.method?(:test) || block.method?(:it) }
47
+ test_blocks = class_node.each_descendant(:block).select { |block_node| test_block?(block_node) }
45
48
 
46
- test_cases + test_blocks
49
+ test_methods + test_blocks
47
50
  end
48
51
 
49
52
  def test_method?(def_node, visibility_check: true)
@@ -52,6 +55,10 @@ module RuboCop
52
55
  test_case_name?(def_node.method_name) && !def_node.arguments?
53
56
  end
54
57
 
58
+ def test_block?(block_node)
59
+ block_node.method?(:test) || block_node.method?(:it)
60
+ end
61
+
55
62
  def lifecycle_hooks(class_node)
56
63
  class_def_nodes(class_node)
57
64
  .select { |def_node| lifecycle_hook_method?(def_node) }
@@ -124,7 +124,7 @@ module RuboCop
124
124
  end
125
125
 
126
126
  def _investigate(cop, processed_source)
127
- team = RuboCop::Cop::Team.new([cop], nil, raise_error: true)
127
+ team = RuboCop::Cop::Team.new([cop], configuration, raise_error: true)
128
128
  report = team.investigate(processed_source)
129
129
  @last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source)
130
130
  report.offenses
@@ -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.27.0'
7
+ STRING = '0.29.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.27.0
4
+ version: 0.29.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: 2023-01-30 00:00:00.000000000 Z
13
+ date: 2023-03-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: '0.90'
21
+ version: '1.39'
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
24
  version: '2.0'
@@ -28,24 +28,10 @@ dependencies:
28
28
  requirements:
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: '0.90'
31
+ version: '1.39'
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
34
  version: '2.0'
35
- - !ruby/object:Gem::Dependency
36
- name: minitest
37
- requirement: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - "~>"
40
- - !ruby/object:Gem::Version
41
- version: '5.11'
42
- type: :development
43
- prerelease: false
44
- version_requirements: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - "~>"
47
- - !ruby/object:Gem::Version
48
- version: '5.11'
49
35
  description: |
50
36
  Automatic Minitest code style checking tool.
51
37
  A RuboCop extension focused on enforcing Minitest best practices and coding conventions.
@@ -82,6 +68,7 @@ files:
82
68
  - lib/rubocop/cop/minitest/duplicate_test_run.rb
83
69
  - lib/rubocop/cop/minitest/empty_line_before_assertion_methods.rb
84
70
  - lib/rubocop/cop/minitest/global_expectations.rb
71
+ - lib/rubocop/cop/minitest/lifecycle_hooks_order.rb
85
72
  - lib/rubocop/cop/minitest/literal_as_actual_argument.rb
86
73
  - lib/rubocop/cop/minitest/multiple_assertions.rb
87
74
  - lib/rubocop/cop/minitest/no_assertions.rb
@@ -125,7 +112,7 @@ metadata:
125
112
  homepage_uri: https://docs.rubocop.org/rubocop-minitest/
126
113
  changelog_uri: https://github.com/rubocop/rubocop-minitest/blob/master/CHANGELOG.md
127
114
  source_code_uri: https://github.com/rubocop/rubocop-minitest
128
- documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.27
115
+ documentation_uri: https://docs.rubocop.org/rubocop-minitest/0.29
129
116
  bug_tracker_uri: https://github.com/rubocop/rubocop-minitest/issues
130
117
  rubygems_mfa_required: 'true'
131
118
  post_install_message: