rubocop-rspec 2.16.0 → 2.17.1

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: c31ad963289938a78bf4a8439ad44c6f1a2eaf852a25d715be483ebe71e622fc
4
- data.tar.gz: 70b4e942004dd6654fa12c3ecaf7367c1f6bcf4bcd122573129984f5f0a66ff5
3
+ metadata.gz: a5f767597141ddcf9b2e28f8f02490b63d2e0e4e2a5804a81383af2c4ae15332
4
+ data.tar.gz: 8f55d65178e33b86fb6b685499876e116dfe2665c1e8da201b462721982dc49c
5
5
  SHA512:
6
- metadata.gz: 250a68082a8e6406df3934035e5ccba4e1a7f9a13e021e196911c15981a2f4557e7b7a98efa93f995ad164d2a52e41bf948f4c1fa7c9637829c3c219c8116f74
7
- data.tar.gz: 7ce965fc56bf214eb65b63d2138cc710766ac16b476a63399271cc5562fb259cefc81cddcf3878f6324faf104d6552e48efcba2eff1fa0865bf463963e5a1a8e
6
+ metadata.gz: 4a42691283f03313b47cd59c36d040f1bd10b7da16bed5f1b96d80bdf65fdc592ad1df94c2288c9e157f8c6a101e028500b3126a40657eb87c2c1345675d1957
7
+ data.tar.gz: f3803001a19e2871f96f18ce9053bb43551298affb4478d20bd3c30edcff7aa814690b5e1f6b978da77d53d17910372202360f307cc52962ce5dd4c600f34dca
data/CHANGELOG.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 2.17.1 (2023-01-16)
6
+
7
+ - Fix a false negative for `RSpec/Pending` when using skipped in metadata is multiline string. ([@ydah])
8
+ - Fix a false positive for `RSpec/NoExpectationExample` when using skipped in metadata is multiline string. ([@ydah])
9
+ - Fix a false positive for `RSpec/ContextMethod` when multi-line context with `#` at the beginning. ([@ydah])
10
+ - Fix an incorrect autocorrect for `RSpec/PredicateMatcher` when multiline expect and predicate method with heredoc. ([@ydah])
11
+ - Fix a false positive for `RSpec/PredicateMatcher` when `include` with multiple argument. ([@ydah])
12
+
13
+ ## 2.17.0 (2023-01-13)
14
+
15
+ - Fix a false positive for `RSpec/PendingWithoutReason` when pending/skip is argument of methods. ([@ydah])
16
+ - Add new `RSpec/Capybara/MatchStyle` cop. ([@ydah])
17
+ - Add new `RSpec/Rails/MinitestAssertions` cop. ([@ydah])
18
+ - Fix a false positive for `RSpec/PendingWithoutReason` when not inside example. ([@ydah])
19
+ - Fix a false negative for `RSpec/PredicateMatcher` when using `include` and `respond_to`. ([@ydah])
20
+ - Fix a false positive for `RSpec/StubbedMock` when stubbed message expectation with a block and block parameter. ([@ydah])
21
+
5
22
  ## 2.16.0 (2022-12-13)
6
23
 
7
24
  - Add new `RSpec/FactoryBot/FactoryNameStyle` cop. ([@ydah])
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Join the chat at https://gitter.im/rubocop-rspec/Lobby](https://badges.gitter.im/rubocop-rspec/Lobby.svg)](https://gitter.im/rubocop-rspec/Lobby)
4
4
  [![Gem Version](https://badge.fury.io/rb/rubocop-rspec.svg)](https://rubygems.org/gems/rubocop-rspec)
5
- ![CI](https://github.com/rubocop-hq/rubocop-rspec/workflows/CI/badge.svg)
5
+ ![CI](https://github.com/rubocop/rubocop-rspec/workflows/CI/badge.svg)
6
6
 
7
7
  RSpec-specific analysis for your projects, as an extension to
8
8
  [RuboCop](https://github.com/rubocop/rubocop).
data/config/default.yml CHANGED
@@ -887,6 +887,12 @@ RSpec/Capybara/FeatureMethods:
887
887
  VersionChanged: '2.0'
888
888
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods
889
889
 
890
+ RSpec/Capybara/MatchStyle:
891
+ Description: Checks for usage of deprecated style methods.
892
+ Enabled: pending
893
+ VersionAdded: '2.17'
894
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/MatchStyle
895
+
890
896
  RSpec/Capybara/NegationMatcher:
891
897
  Description: Enforces use of `have_no_*` or `not_to` for negated expectations.
892
898
  Enabled: pending
@@ -1044,3 +1050,9 @@ RSpec/Rails/InferredSpecType:
1044
1050
  routing: routing
1045
1051
  system: system
1046
1052
  views: view
1053
+
1054
+ RSpec/Rails/MinitestAssertions:
1055
+ Description: Check if using Minitest matchers.
1056
+ Enabled: pending
1057
+ VersionAdded: '2.17'
1058
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/MinitestAssertions
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ module Capybara
7
+ # Checks for usage of deprecated style methods.
8
+ #
9
+ # @example when using `assert_style`
10
+ # # bad
11
+ # page.find(:css, '#first').assert_style(display: 'block')
12
+ #
13
+ # # good
14
+ # page.find(:css, '#first').assert_matches_style(display: 'block')
15
+ #
16
+ # @example when using `has_style?`
17
+ # # bad
18
+ # expect(page.find(:css, 'first')
19
+ # .has_style?(display: 'block')).to be true
20
+ #
21
+ # # good
22
+ # expect(page.find(:css, 'first')
23
+ # .matches_style?(display: 'block')).to be true
24
+ #
25
+ # @example when using `have_style`
26
+ # # bad
27
+ # expect(page).to have_style(display: 'block')
28
+ #
29
+ # # good
30
+ # expect(page).to match_style(display: 'block')
31
+ #
32
+ class MatchStyle < Base
33
+ extend AutoCorrector
34
+
35
+ MSG = 'Use `%<good>s` instead of `%<bad>s`.'
36
+ RESTRICT_ON_SEND = %i[assert_style has_style? have_style].freeze
37
+ PREFERRED_METHOD = {
38
+ 'assert_style' => 'assert_matches_style',
39
+ 'has_style?' => 'matches_style?',
40
+ 'have_style' => 'match_style'
41
+ }.freeze
42
+
43
+ def on_send(node)
44
+ method_node = node.loc.selector
45
+ add_offense(method_node) do |corrector|
46
+ corrector.replace(method_node,
47
+ PREFERRED_METHOD[method_node.source])
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def message(node)
54
+ format(MSG, good: PREFERRED_METHOD[node.source], bad: node.source)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -31,7 +31,11 @@ module RuboCop
31
31
 
32
32
  # @!method context_method(node)
33
33
  def_node_matcher :context_method, <<-PATTERN
34
- (block (send #rspec? :context $(str #method_name?) ...) ...)
34
+ (block
35
+ (send #rspec? :context
36
+ ${(str #method_name?) (dstr (str #method_name?) ...)}
37
+ ...)
38
+ ...)
35
39
  PATTERN
36
40
 
37
41
  def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
@@ -10,7 +10,6 @@ module RuboCop
10
10
  # include `if`, `unless`, `for`, `before`, `after`, or `during`.
11
11
  # They may consist of multiple words if desired.
12
12
  #
13
- # @see https://rspec.rubystyle.guide/#context-descriptions
14
13
  # @see http://www.betterspecs.org/#contexts
15
14
  #
16
15
  # @example `Prefixes` configuration
@@ -11,7 +11,7 @@ module RuboCop
11
11
  def_node_matcher :skipped_in_metadata?, <<-PATTERN
12
12
  {
13
13
  (send _ _ <#skip_or_pending? ...>)
14
- (send _ _ ... (hash <(pair #skip_or_pending? { true str }) ...>))
14
+ (send _ _ ... (hash <(pair #skip_or_pending? { true str dstr }) ...>))
15
15
  }
16
16
  PATTERN
17
17
 
@@ -87,35 +87,33 @@ module RuboCop
87
87
  (send #rspec? {#ExampleGroups.all #Examples.all} ... {<(sym :skip) ...> (hash <(pair (sym :skip) true) ...>)})
88
88
  PATTERN
89
89
 
90
+ # @!method without_reason?(node)
91
+ def_node_matcher :without_reason?, <<~PATTERN
92
+ (send nil? ${:pending :skip})
93
+ PATTERN
94
+
90
95
  def on_send(node)
91
96
  if pending_without_reason?(node)
92
97
  add_offense(node, message: 'Give the reason for pending.')
93
98
  elsif skipped_without_reason?(node)
94
99
  add_offense(node, message: 'Give the reason for skip.')
100
+ elsif without_reason?(node) && example?(node.parent)
101
+ add_offense(node,
102
+ message: "Give the reason for #{node.method_name}.")
95
103
  end
96
104
  end
97
105
 
98
106
  private
99
107
 
100
- def pending_by_pending_step_without_reason?(node)
101
- node.method?(:pending) && node.first_argument.nil?
102
- end
103
-
104
108
  def pending_without_reason?(node)
105
109
  pending_by_example_method?(node.block_node) ||
106
- pending_by_metadata_without_reason?(node) ||
107
- pending_by_pending_step_without_reason?(node)
108
- end
109
-
110
- def skipped_by_skip_step_without_reason?(node)
111
- node.method?(:skip) && node.first_argument.nil?
110
+ pending_by_metadata_without_reason?(node)
112
111
  end
113
112
 
114
113
  def skipped_without_reason?(node)
115
114
  skipped_by_example_group_method?(node.block_node) ||
116
115
  skipped_by_example_method?(node.block_node) ||
117
- skipped_by_metadata_without_reason?(node) ||
118
- skipped_by_skip_step_without_reason?(node)
116
+ skipped_by_metadata_without_reason?(node)
119
117
  end
120
118
  end
121
119
  end
@@ -118,7 +118,7 @@ module RuboCop
118
118
  end
119
119
 
120
120
  # A helper for `explicit` style
121
- module ExplicitHelper
121
+ module ExplicitHelper # rubocop:disable Metrics/ModuleLength
122
122
  include RuboCop::RSpec::Language
123
123
  extend NodePattern::Macros
124
124
 
@@ -149,12 +149,35 @@ module RuboCop
149
149
  return if part_of_ignored_node?(node)
150
150
 
151
151
  predicate_matcher?(node) do |actual, matcher|
152
+ next unless replaceable_matcher?(matcher)
153
+
152
154
  add_offense(node, message: message_explicit(matcher)) do |corrector|
155
+ next if uncorrectable_matcher?(node, matcher)
156
+
153
157
  corrector_explicit(corrector, node, actual, matcher, matcher)
154
158
  end
155
159
  end
156
160
  end
157
161
 
162
+ def replaceable_matcher?(matcher)
163
+ case matcher.method_name.to_s
164
+ when 'include'
165
+ matcher.arguments.one?
166
+ else
167
+ true
168
+ end
169
+ end
170
+
171
+ def uncorrectable_matcher?(node, matcher)
172
+ heredoc_argument?(matcher) && !same_line?(node, matcher)
173
+ end
174
+
175
+ def heredoc_argument?(matcher)
176
+ matcher.arguments.select do |arg|
177
+ %i[str dstr xstr].include?(arg.type)
178
+ end.any?(&:heredoc?)
179
+ end
180
+
158
181
  # @!method predicate_matcher?(node)
159
182
  def_node_matcher :predicate_matcher?, <<-PATTERN
160
183
  (send
@@ -179,7 +202,8 @@ module RuboCop
179
202
 
180
203
  return false if allowed_explicit_matchers.include?(name)
181
204
 
182
- name.start_with?('be_', 'have_') && !name.end_with?('?')
205
+ name.start_with?('be_', 'have_') && !name.end_with?('?') ||
206
+ %w[include respond_to].include?(name)
183
207
  end
184
208
 
185
209
  def message_explicit(matcher)
@@ -270,6 +294,17 @@ module RuboCop
270
294
  # # good - the above code is rewritten to it by this cop
271
295
  # expect(foo.something?).to be(true)
272
296
  #
297
+ # # bad - no autocorrect
298
+ # expect(foo)
299
+ # .to be_something(<<~TEXT)
300
+ # bar
301
+ # TEXT
302
+ #
303
+ # # good
304
+ # expect(foo.something?(<<~TEXT)).to be(true)
305
+ # bar
306
+ # TEXT
307
+ #
273
308
  # @example Strict: false, EnforcedStyle: explicit
274
309
  # # bad
275
310
  # expect(foo).to be_something
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ module Rails
7
+ # Check if using Minitest matchers.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # assert_equal(a, b)
12
+ # assert_equal a, b, "must be equal"
13
+ # refute_equal(a, b)
14
+ #
15
+ # # good
16
+ # expect(a).to eq(b)
17
+ # expect(a).to(eq(b), "must be equal")
18
+ # expect(a).not_to eq(b)
19
+ #
20
+ class MinitestAssertions < Base
21
+ extend AutoCorrector
22
+
23
+ MSG = 'Use `%<prefer>s`.'
24
+ RESTRICT_ON_SEND = %i[assert_equal refute_equal].freeze
25
+
26
+ # @!method minitest_assertion(node)
27
+ def_node_matcher :minitest_assertion, <<-PATTERN
28
+ (send nil? {:assert_equal :refute_equal} $_ $_ $_?)
29
+ PATTERN
30
+
31
+ def on_send(node)
32
+ minitest_assertion(node) do |expected, actual, failure_message|
33
+ prefer = replacement(node, expected, actual,
34
+ failure_message.first)
35
+ add_offense(node, message: message(prefer)) do |corrector|
36
+ corrector.replace(node, prefer)
37
+ end
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def replacement(node, expected, actual, failure_message)
44
+ runner = node.method?(:assert_equal) ? 'to' : 'not_to'
45
+ if failure_message.nil?
46
+ "expect(#{expected.source}).#{runner} eq(#{actual.source})"
47
+ else
48
+ "expect(#{expected.source}).#{runner}(eq(#{actual.source}), " \
49
+ "#{failure_message.source})"
50
+ end
51
+ end
52
+
53
+ def message(prefer)
54
+ format(MSG, prefer: prefer)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -91,7 +91,7 @@ module RuboCop
91
91
  # @param node [RuboCop::AST::Node]
92
92
  # @yield [RuboCop::AST::Node] matcher
93
93
  def_node_matcher :matcher_with_return_block, <<~PATTERN
94
- (block #message_expectation? args _) # receive(:foo) { 'bar' }
94
+ (block #message_expectation? (args) _) # receive(:foo) { 'bar' }
95
95
  PATTERN
96
96
 
97
97
  # @!method matcher_with_hash(node)
@@ -12,7 +12,6 @@ module RuboCop
12
12
  #
13
13
  # @see https://robots.thoughtbot.com/don-t-stub-the-system-under-test
14
14
  # @see https://penelope.zone/2015/12/27/introducing-rspec-smells-and-where-to-find-them.html#smell-1-stubjec
15
- # @see https://github.com/rubocop-hq/rspec-style-guide#dont-stub-subject
16
15
  #
17
16
  # @example
18
17
  # # bad
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'rspec/capybara/current_path_expectation'
4
4
  require_relative 'rspec/capybara/feature_methods'
5
+ require_relative 'rspec/capybara/match_style'
5
6
  require_relative 'rspec/capybara/negation_matcher'
6
7
  require_relative 'rspec/capybara/specific_actions'
7
8
  require_relative 'rspec/capybara/specific_finders'
@@ -23,6 +24,7 @@ rescue LoadError
23
24
  # Rails/HttpStatus cannot be loaded if rack/utils is unavailable.
24
25
  end
25
26
  require_relative 'rspec/rails/inferred_spec_type'
27
+ require_relative 'rspec/rails/minitest_assertions'
26
28
 
27
29
  require_relative 'rspec/align_left_let_brace'
28
30
  require_relative 'rspec/align_right_let_brace'
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module RSpec
5
5
  # Version information for the RSpec RuboCop plugin.
6
6
  module Version
7
- STRING = '2.16.0'
7
+ STRING = '2.17.1'
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.16.0
4
+ version: 2.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Backus
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-12-13 00:00:00.000000000 Z
13
+ date: 2023-01-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -58,6 +58,7 @@ files:
58
58
  - lib/rubocop/cop/rspec/before_after_all.rb
59
59
  - lib/rubocop/cop/rspec/capybara/current_path_expectation.rb
60
60
  - lib/rubocop/cop/rspec/capybara/feature_methods.rb
61
+ - lib/rubocop/cop/rspec/capybara/match_style.rb
61
62
  - lib/rubocop/cop/rspec/capybara/negation_matcher.rb
62
63
  - lib/rubocop/cop/rspec/capybara/specific_actions.rb
63
64
  - lib/rubocop/cop/rspec/capybara/specific_finders.rb
@@ -142,6 +143,7 @@ files:
142
143
  - lib/rubocop/cop/rspec/rails/have_http_status.rb
143
144
  - lib/rubocop/cop/rspec/rails/http_status.rb
144
145
  - lib/rubocop/cop/rspec/rails/inferred_spec_type.rb
146
+ - lib/rubocop/cop/rspec/rails/minitest_assertions.rb
145
147
  - lib/rubocop/cop/rspec/receive_counts.rb
146
148
  - lib/rubocop/cop/rspec/receive_never.rb
147
149
  - lib/rubocop/cop/rspec/repeated_description.rb
@@ -207,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
209
  - !ruby/object:Gem::Version
208
210
  version: '0'
209
211
  requirements: []
210
- rubygems_version: 3.1.6
212
+ rubygems_version: 3.3.7
211
213
  signing_key:
212
214
  specification_version: 4
213
215
  summary: Code style checking for RSpec files