rubocop-rspec_rails 2.31.0 → 2.33.0

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: a532f361a0657a600a657dd22a2344028ce648996179c8c4df27ea29302537ac
4
- data.tar.gz: f7d10a791b1c5ee7d6a4444ee15eea12622cec6ecfd2174fafe037d37651a6bb
3
+ metadata.gz: a42fb50c1cc6fac2f7c5a5c81dcf9573d4cbc27390157cc0063b907c880b12ae
4
+ data.tar.gz: b4e95f46c045360b80c76177b975ba2932c247974e63d56cd7e376b176831288
5
5
  SHA512:
6
- metadata.gz: 976d9b3320ea2923c627597dc7cffb0e0f212ea16430084e60c53345093cebc4dff74e28ee7730900e0955920e2f7fee8f7206c4b583731d9cc58d5c67d67688
7
- data.tar.gz: 657c590a5cb85f4f3b97b08f5dfc57409b07392db055ea1f0e2f7a04e78cd6d9920ca21f298c5d9c3120dc971776fb5429213d576cb91e4ae85713da704dc30a
6
+ metadata.gz: 594c53b8d30e097e94063476fd9d42d014ae3f4913a029956b66a9c25be1064d8136bedeea8247e7845bfd6278b614a8a7ea7da2a71e1677739500c44ce24782
7
+ data.tar.gz: 7318471ee0e4062142c4a64ca3ad5a718d7d00c6653d6210d7345bbf60208fe51f8b4c815849e369daecf3810d59d351c69b330ddb7130c028b89cbeb21af152
data/CHANGELOG.md CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 2.33.0 (2026-10-07)
6
+
7
+ - Add `RSpecRails/FileFixture` cop to prefer `file_fixture` over hardcoded fixture paths. ([@ydah])
8
+ - Fix `RSpecRails/HttpStatus` to detect unknown symbolic HTTP statuses and handle custom numeric string statuses consistently. ([@ydah])
9
+ - Speed up loading rubocop-rspec_rails by lazily loading only the cops needed for a run. This requires RuboCop 1.89.0+. ([@koic])
10
+ - Fix offense message for `RSpecRails/HttpStatusNameConsistency` cop. ([@fatkodima])
11
+ - Fix `RSpecRails/MinitestAssertions` autocorrection for quoted predicate symbols. ([@ydah])
12
+ - Fix `RSpecRails/AvoidSetupHook` to only check setup hooks inside example groups. ([@ydah])
13
+ - Fix a false positive for `RspecRails/NegationBeValid` when use `to_not`. ([@ydah])
14
+ - Fix false positives for `RSpecRails/TravelAround` when travel does not directly wrap the around example. ([@ydah])
15
+ - Supporting correcting `assest_redirected_to` in `RSpec/Rails/MinitestAssertions`. ([@nzlaura])
16
+ - Add new `RSpecRails/ReceivePerformLater` cop. ([@ydah])
17
+ - Fix `RSpecRails/ReceivePerformLater` offense range to exclude chains after the expectation. ([@ydah])
18
+ - Fix a false positive for `RSpecRails/ReceivePerformLater` when `receive(:perform_later)` is used inside another matcher. ([@ydah])
19
+ - Support `described_class` for `RSpecRails/ReceivePerformLater`. ([@ydah])
20
+ - Fix `RSpecRails/TravelAround` autocorrection to keep the indentation of the surrounding `around` block. ([@eugeneius])
21
+ - Fix `RSpecRails/ReceivePerformLater` offense messages for negative expectations. ([@ydah])
22
+
23
+ ## 2.32.0 (2025-11-12)
24
+
25
+ - Add `RSpecRails/HttpStatusNameConsistency` cop. ([@taketo1113])
26
+ - Support correcting `assert_response` assertion in in `RSpec/Rails/MinitestAssertions`. ([@nzlaura])
27
+
5
28
  ## 2.31.0 (2025-03-10)
6
29
 
7
30
  - Handle unknown HTTP status codes for `RSpecRails/HttpStatus` cop. ([@viralpraxis])
@@ -78,14 +101,19 @@
78
101
  [@anthony-robin]: https://github.com/anthony-robin
79
102
  [@bquorning]: https://github.com/bquorning
80
103
  [@corydiamand]: https://github.com/corydiamand
104
+ [@eugeneius]: https://github.com/eugeneius
105
+ [@fatkodima]: https://github.com/fatkodima
81
106
  [@g-rath]: https://github.com/G-Rath
82
107
  [@jojos003]: https://github.com/jojos003
108
+ [@koic]: https://github.com/koic
83
109
  [@mothonmars]: https://github.com/MothOnMars
84
110
  [@mvz]: https://github.com/mvz
111
+ [@nzlaura]: https://github.com/nzlaura
85
112
  [@paydaylight]: https://github.com/paydaylight
86
113
  [@pirj]: https://github.com/pirj
87
114
  [@r7kamura]: https://github.com/r7kamura
88
115
  [@splattael]: https://github.com/splattael
116
+ [@taketo1113]: https://github.com/taketo1113
89
117
  [@tmaier]: https://github.com/tmaier
90
118
  [@viralpraxis]: https://github.com/viralpraxis
91
119
  [@ydah]: https://github.com/ydah
data/config/default.yml CHANGED
@@ -7,11 +7,18 @@ RSpecRails:
7
7
  - "**/spec/**/*"
8
8
 
9
9
  RSpecRails/AvoidSetupHook:
10
- Description: Checks that tests use RSpec `before` hook over Rails `setup` method.
10
+ Description: Checks that tests use RSpec `before` instead of Rails `setup`.
11
11
  Enabled: pending
12
12
  VersionAdded: '2.4'
13
13
  Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/AvoidSetupHook
14
14
 
15
+ RSpecRails/FileFixture:
16
+ Description: Prefer `file_fixture` over hardcoded paths into `spec/fixtures`.
17
+ Enabled: pending
18
+ Safe: false
19
+ VersionAdded: '2.33'
20
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/FileFixture
21
+
15
22
  RSpecRails/HaveHttpStatus:
16
23
  Description: Checks that tests use `have_http_status` instead of equality matchers.
17
24
  Enabled: pending
@@ -35,6 +42,12 @@ RSpecRails/HttpStatus:
35
42
  VersionChanged: '2.20'
36
43
  Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/HttpStatus
37
44
 
45
+ RSpecRails/HttpStatusNameConsistency:
46
+ Description: Enforces consistency by using the current HTTP status names.
47
+ Enabled: pending
48
+ VersionAdded: '2.32'
49
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/HttpStatusNameConsistency
50
+
38
51
  RSpecRails/InferredSpecType:
39
52
  Description: Identifies redundant spec type.
40
53
  Enabled: pending
@@ -59,7 +72,7 @@ RSpecRails/InferredSpecType:
59
72
  views: view
60
73
 
61
74
  RSpecRails/MinitestAssertions:
62
- Description: Check if using Minitest-like matchers.
75
+ Description: Detects Minitest-like matchers.
63
76
  Enabled: pending
64
77
  VersionAdded: '2.17'
65
78
  Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/MinitestAssertions
@@ -77,8 +90,14 @@ RSpecRails/NegationBeValid:
77
90
  VersionChanged: '2.29'
78
91
  Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/NegationBeValid
79
92
 
93
+ RSpecRails/ReceivePerformLater:
94
+ Description: Prefer `have_enqueued_job` over `receive(:perform_later)`.
95
+ Enabled: pending
96
+ VersionAdded: '2.33'
97
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/ReceivePerformLater
98
+
80
99
  RSpecRails/TravelAround:
81
- Description: Prefer to travel in `before` rather than `around`.
100
+ Description: Checks for time travel helpers in `around` hooks.
82
101
  Enabled: pending
83
102
  Safe: false
84
103
  VersionAdded: '2.19'
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpecRails
6
- # Checks that tests use RSpec `before` hook over Rails `setup` method.
6
+ # Checks that tests use RSpec `before` instead of Rails `setup`.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -16,8 +16,9 @@ module RuboCop
16
16
  # allow(foo).to receive(:bar)
17
17
  # end
18
18
  #
19
- class AvoidSetupHook < ::RuboCop::Cop::Base
19
+ class AvoidSetupHook < RuboCop::Cop::RSpec::Base
20
20
  extend AutoCorrector
21
+ include RuboCop::Cop::RSpec::InsideExampleGroup
21
22
 
22
23
  MSG = 'Use `before` instead of `setup`.'
23
24
 
@@ -28,7 +29,9 @@ module RuboCop
28
29
  (args) _)
29
30
  PATTERN
30
31
 
31
- def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
32
+ def on_block(node) # rubocop:disable InternalAffairs/ItblockHandler, InternalAffairs/NumblockHandler
33
+ return unless inside_example_group?(node)
34
+
32
35
  setup_call(node) do |setup|
33
36
  add_offense(node) do |corrector|
34
37
  corrector.replace setup, 'before'
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpecRails
6
+ # Prefer `file_fixture` over hardcoded paths into `spec/fixtures`.
7
+ #
8
+ # @safety
9
+ # `file_fixture` uses the configured `file_fixture_path`, which defaults
10
+ # to `spec/fixtures/files`. A file under `spec/fixtures` may need to be
11
+ # moved or `file_fixture_path` configured before replacing the path.
12
+ #
13
+ # @example
14
+ # # bad
15
+ # Rails.root.join('spec', 'fixtures', 'files', 'example.pdf')
16
+ #
17
+ # # good
18
+ # file_fixture('example.pdf')
19
+ class FileFixture < RuboCop::Cop::Base
20
+ MSG = 'Prefer `file_fixture` for files under `spec/fixtures`.'
21
+ RESTRICT_ON_SEND = %i[join].freeze
22
+
23
+ # @!method fixture_path?(node)
24
+ def_node_matcher :fixture_path?, <<~PATTERN
25
+ (send
26
+ (send (const {nil? cbase} :Rails) :root)
27
+ :join (str "spec") (str "fixtures") _ ...)
28
+ PATTERN
29
+
30
+ # @!method combined_fixture_path?(node)
31
+ def_node_matcher :combined_fixture_path?, <<~PATTERN
32
+ (send
33
+ (send (const {nil? cbase} :Rails) :root)
34
+ :join (str "spec/fixtures") _ ...)
35
+ PATTERN
36
+
37
+ def on_send(node)
38
+ return unless fixture_path?(node) || combined_fixture_path?(node)
39
+
40
+ add_offense(node.loc.selector)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -5,7 +5,11 @@ module RuboCop
5
5
  module RSpecRails
6
6
  # Checks that tests use `have_http_status` instead of equality matchers.
7
7
  #
8
- # @example ResponseMethods: ['response', 'last_response'] (default)
8
+ # @safety
9
+ # The autocorrection is marked as unsafe because
10
+ # `response.status` response is not always an HTTP response status.
11
+ #
12
+ # @example `ResponseMethods: ['response', 'last_response']` (default)
9
13
  # # bad
10
14
  # expect(response.status).to be(200)
11
15
  # expect(last_response.code).to eq("200")
@@ -14,7 +18,7 @@ module RuboCop
14
18
  # expect(response).to have_http_status(200)
15
19
  # expect(last_response).to have_http_status(200)
16
20
  #
17
- # @example ResponseMethods: ['foo_response']
21
+ # @example `ResponseMethods: ['foo_response']`
18
22
  # # bad
19
23
  # expect(foo_response.status).to be(200)
20
24
  #
@@ -25,7 +29,7 @@ module RuboCop
25
29
  # expect(response).to have_http_status(200)
26
30
  # expect(last_response).to have_http_status(200)
27
31
  #
28
- class HaveHttpStatus < ::RuboCop::Cop::Base
32
+ class HaveHttpStatus < RuboCop::Cop::Base
29
33
  extend AutoCorrector
30
34
 
31
35
  MSG =
@@ -64,9 +64,10 @@ module RuboCop
64
64
  #
65
65
  # # good
66
66
  # it { is_expected.to have_http_status :ok }
67
- class HttpStatus < ::RuboCop::Cop::Base
67
+ class HttpStatus < RuboCop::Cop::Base
68
68
  extend AutoCorrector
69
69
  include ConfigurableEnforcedStyle
70
+
70
71
  RESTRICT_ON_SEND = %i[have_http_status].freeze
71
72
 
72
73
  # @!method http_status(node)
@@ -142,16 +143,44 @@ module RuboCop
142
143
  node.sym_type? && ALLOWED_STATUSES.include?(node.value)
143
144
  end
144
145
 
146
+ def known_status_symbol?
147
+ node.sym_type? &&
148
+ ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key?(node.value)
149
+ end
150
+
151
+ def known_status_code?
152
+ numeric_status_code? &&
153
+ ::Rack::Utils::SYMBOL_TO_STATUS_CODE.value?(status_code_number)
154
+ end
155
+
145
156
  def custom_http_status_code?
146
- node.int_type? &&
147
- !::Rack::Utils::SYMBOL_TO_STATUS_CODE.value?(node.source.to_i)
157
+ numeric_status_code? && !known_status_code?
158
+ end
159
+
160
+ def numeric_status_code?
161
+ node.int_type? || numeric_string?
162
+ end
163
+
164
+ def numeric_string?
165
+ node.str_type? && node.value.match?(/\A\d+\z/)
166
+ end
167
+
168
+ def status_code_number
169
+ node.value.to_i
170
+ end
171
+
172
+ def status_code_symbol
173
+ ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(status_code_number)
148
174
  end
149
175
  end
150
176
 
151
177
  # :nodoc:
152
178
  class SymbolicStyleChecker < StyleCheckerBase
153
179
  def offensive?
154
- !node.sym_type? && !custom_http_status_code?
180
+ return false if allowed_symbol? || known_status_symbol?
181
+ return false if custom_http_status_code?
182
+
183
+ true
155
184
  end
156
185
 
157
186
  def autocorrectable?
@@ -165,18 +194,17 @@ module RuboCop
165
194
  private
166
195
 
167
196
  def symbol
168
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
169
- end
170
-
171
- def number
172
- node.value.to_i
197
+ status_code_symbol if known_status_code?
173
198
  end
174
199
  end
175
200
 
176
201
  # :nodoc:
177
202
  class NumericStyleChecker < StyleCheckerBase
178
203
  def offensive?
179
- !node.int_type? && !allowed_symbol?
204
+ return false if node.int_type? || allowed_symbol?
205
+ return false if custom_http_status_code?
206
+
207
+ true
180
208
  end
181
209
 
182
210
  def autocorrectable?
@@ -189,20 +217,19 @@ module RuboCop
189
217
 
190
218
  private
191
219
 
192
- def symbol
193
- node.value
194
- end
195
-
196
220
  def number
197
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE[symbol.to_sym]
221
+ return status_code_number if known_status_code?
222
+
223
+ ::Rack::Utils::SYMBOL_TO_STATUS_CODE[node.value.to_sym]
198
224
  end
199
225
  end
200
226
 
201
227
  # :nodoc:
202
228
  class BeStatusStyleChecker < StyleCheckerBase
203
229
  def offensive?
204
- (!node.sym_type? && !custom_http_status_code?) ||
205
- (!node.int_type? && !allowed_symbol?)
230
+ return false if allowed_symbol? || custom_http_status_code?
231
+
232
+ true
206
233
  end
207
234
 
208
235
  def autocorrectable?
@@ -220,30 +247,18 @@ module RuboCop
220
247
  private
221
248
 
222
249
  def status_code
223
- if node.sym_type?
250
+ if known_status_symbol?
224
251
  node.value
225
- elsif node.int_type?
226
- symbol
252
+ elsif known_status_code?
253
+ status_code_symbol
227
254
  else
228
255
  normalize_str
229
256
  end
230
257
  end
231
258
 
232
- def symbol
233
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
234
- end
235
-
236
- def number
237
- node.value.to_i
238
- end
239
-
240
259
  def normalize_str
241
260
  str = node.value.to_s
242
- if str.match?(/\A\d+\z/)
243
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(str.to_i)
244
- elsif ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key?(str.to_sym)
245
- str
246
- end
261
+ str if ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key?(str.to_sym)
247
262
  end
248
263
  end
249
264
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpecRails
6
+ # Enforces consistency by using the current HTTP status names.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # it { is_expected.to have_http_status :unprocessable_entity }
12
+ #
13
+ # # good
14
+ # it { is_expected.to have_http_status :unprocessable_content }
15
+ #
16
+ class HttpStatusNameConsistency < RuboCop::Cop::Base
17
+ extend AutoCorrector
18
+
19
+ requires_gem 'rack', '>= 3.1.0'
20
+
21
+ MSG = 'Prefer `:%<preferred>s` over `:%<current>s`.'
22
+
23
+ RESTRICT_ON_SEND = %i[have_http_status].freeze
24
+
25
+ PREFERRED_STATUSES = {
26
+ unprocessable_entity: :unprocessable_content,
27
+ payload_too_large: :content_too_large
28
+ }.freeze
29
+
30
+ # @!method http_status(node)
31
+ def_node_matcher :http_status, <<~PATTERN
32
+ (send nil? :have_http_status ${sym})
33
+ PATTERN
34
+
35
+ def on_send(node)
36
+ http_status(node) do |arg|
37
+ check_status_name_consistency(arg)
38
+ end
39
+ end
40
+ alias on_csend on_send
41
+
42
+ private
43
+
44
+ def check_status_name_consistency(node)
45
+ return unless node.sym_type? && PREFERRED_STATUSES.key?(node.value)
46
+
47
+ current_status = node.value
48
+ preferred_status = PREFERRED_STATUSES[current_status]
49
+
50
+ message = format(MSG, current: current_status,
51
+ preferred: preferred_status)
52
+
53
+ add_offense(node, message: message) do |corrector|
54
+ corrector.replace(node, ":#{preferred_status}")
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -30,12 +30,7 @@ module RuboCop
30
30
  # RSpec.describe User, type: :common do
31
31
  # end
32
32
  #
33
- # @example `Inferences` configuration
34
- # # .rubocop.yml
35
- # # RSpecRails/InferredSpecType:
36
- # # Inferences:
37
- # # services: service
38
- #
33
+ # @example `Inferences: {services: service}`
39
34
  # # bad
40
35
  # # spec/services/user_spec.rb
41
36
  # RSpec.describe User, type: :service do
@@ -50,13 +45,13 @@ module RuboCop
50
45
  # # spec/services/user_spec.rb
51
46
  # RSpec.describe User, type: :common do
52
47
  # end
53
- class InferredSpecType < ::RuboCop::Cop::RSpec::Base
48
+ class InferredSpecType < RuboCop::Cop::RSpec::Base
54
49
  extend AutoCorrector
55
50
 
56
51
  MSG = 'Remove redundant spec type.'
57
52
 
58
53
  # @param [RuboCop::AST::BlockNode] node
59
- def on_block(node)
54
+ def on_block(node) # rubocop:disable InternalAffairs/ItblockHandler
60
55
  return unless example_group?(node)
61
56
 
62
57
  pair_node = describe_with_type(node)
@@ -3,10 +3,10 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpecRails
6
- # Check if using Minitest-like matchers.
6
+ # Detects Minitest-like matchers.
7
7
  #
8
- # Check the use of minitest-like matchers
9
- # starting with `assert_` or `refute_`.
8
+ # Detects the use of Minitest-like matchers
9
+ # (those starting with `assert_` or `refute_`).
10
10
  #
11
11
  # @example
12
12
  # # bad
@@ -18,6 +18,8 @@ module RuboCop
18
18
  # refute_empty(b)
19
19
  # assert_true(a)
20
20
  # assert_false(a)
21
+ # assert_response :ok
22
+ # assert_redirected_to '/users'
21
23
  #
22
24
  # # good
23
25
  # expect(b).to eq(a)
@@ -28,8 +30,10 @@ module RuboCop
28
30
  # expect(a).not_to be_empty
29
31
  # expect(a).to be(true)
30
32
  # expect(a).to be(false)
33
+ # expect(response).to have_http_status(:ok)
34
+ # expect(response).to redirect_to('/users')
31
35
  #
32
- class MinitestAssertions < ::RuboCop::Cop::Base
36
+ class MinitestAssertions < RuboCop::Cop::Base
33
37
  extend AutoCorrector
34
38
 
35
39
  # :nodoc:
@@ -38,12 +42,25 @@ module RuboCop
38
42
 
39
43
  attr_reader :expected, :actual, :failure_message
40
44
 
45
+ def self.match_assertions(*matchers, captures:)
46
+ const_set(:MATCHERS, matchers.freeze)
47
+
48
+ matcher_pattern = matchers.map { |matcher| ":#{matcher}" }.join(' ')
49
+ def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
50
+ (send nil? {#{matcher_pattern}} #{captures})
51
+ PATTERN
52
+ end
53
+
41
54
  def self.minitest_assertion
42
55
  # :nocov:
43
56
  raise NotImplementedError
44
57
  # :nocov:
45
58
  end
46
59
 
60
+ def self.match(expected, actual, failure_message)
61
+ new(expected, actual, failure_message.first)
62
+ end
63
+
47
64
  def initialize(expected, actual, failure_message)
48
65
  @expected = expected&.source
49
66
  @actual = actual.source
@@ -72,20 +89,10 @@ module RuboCop
72
89
 
73
90
  # :nodoc:
74
91
  class EqualAssertion < BasicAssertion
75
- MATCHERS = %i[
76
- assert_equal
77
- assert_not_equal
78
- refute_equal
79
- ].freeze
80
-
81
- # @!method self.minitest_assertion(node)
82
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
83
- (send nil? {:assert_equal :assert_not_equal :refute_equal} $_ $_ $_?)
84
- PATTERN
85
-
86
- def self.match(expected, actual, failure_message)
87
- new(expected, actual, failure_message.first)
88
- end
92
+ match_assertions :assert_equal,
93
+ :assert_not_equal,
94
+ :refute_equal,
95
+ captures: '$_ $_ $_?'
89
96
 
90
97
  def assertion
91
98
  "eq(#{expected})"
@@ -94,20 +101,10 @@ module RuboCop
94
101
 
95
102
  # :nodoc:
96
103
  class KindOfAssertion < BasicAssertion
97
- MATCHERS = %i[
98
- assert_kind_of
99
- assert_not_kind_of
100
- refute_kind_of
101
- ].freeze
102
-
103
- # @!method self.minitest_assertion(node)
104
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
105
- (send nil? {:assert_kind_of :assert_not_kind_of :refute_kind_of} $_ $_ $_?)
106
- PATTERN
107
-
108
- def self.match(expected, actual, failure_message)
109
- new(expected, actual, failure_message.first)
110
- end
104
+ match_assertions :assert_kind_of,
105
+ :assert_not_kind_of,
106
+ :refute_kind_of,
107
+ captures: '$_ $_ $_?'
111
108
 
112
109
  def assertion
113
110
  "be_a_kind_of(#{expected})"
@@ -116,20 +113,10 @@ module RuboCop
116
113
 
117
114
  # :nodoc:
118
115
  class InstanceOfAssertion < BasicAssertion
119
- MATCHERS = %i[
120
- assert_instance_of
121
- assert_not_instance_of
122
- refute_instance_of
123
- ].freeze
124
-
125
- # @!method self.minitest_assertion(node)
126
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
127
- (send nil? {:assert_instance_of :assert_not_instance_of :refute_instance_of} $_ $_ $_?)
128
- PATTERN
129
-
130
- def self.match(expected, actual, failure_message)
131
- new(expected, actual, failure_message.first)
132
- end
116
+ match_assertions :assert_instance_of,
117
+ :assert_not_instance_of,
118
+ :refute_instance_of,
119
+ captures: '$_ $_ $_?'
133
120
 
134
121
  def assertion
135
122
  "be_an_instance_of(#{expected})"
@@ -138,16 +125,10 @@ module RuboCop
138
125
 
139
126
  # :nodoc:
140
127
  class IncludesAssertion < BasicAssertion
141
- MATCHERS = %i[
142
- assert_includes
143
- assert_not_includes
144
- refute_includes
145
- ].freeze
146
-
147
- # @!method self.minitest_assertion(node)
148
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
149
- (send nil? {:assert_includes :assert_not_includes :refute_includes} $_ $_ $_?)
150
- PATTERN
128
+ match_assertions :assert_includes,
129
+ :assert_not_includes,
130
+ :refute_includes,
131
+ captures: '$_ $_ $_?'
151
132
 
152
133
  def self.match(collection, expected, failure_message)
153
134
  new(expected, collection, failure_message.first)
@@ -160,16 +141,10 @@ module RuboCop
160
141
 
161
142
  # :nodoc:
162
143
  class InDeltaAssertion < BasicAssertion
163
- MATCHERS = %i[
164
- assert_in_delta
165
- assert_not_in_delta
166
- refute_in_delta
167
- ].freeze
168
-
169
- # @!method self.minitest_assertion(node)
170
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
171
- (send nil? {:assert_in_delta :assert_not_in_delta :refute_in_delta} $_ $_ $_? $_?)
172
- PATTERN
144
+ match_assertions :assert_in_delta,
145
+ :assert_not_in_delta,
146
+ :refute_in_delta,
147
+ captures: '$_ $_ $_? $_?'
173
148
 
174
149
  def self.match(expected, actual, delta, failure_message)
175
150
  new(expected, actual, delta.first, failure_message.first)
@@ -188,43 +163,41 @@ module RuboCop
188
163
 
189
164
  # :nodoc:
190
165
  class PredicateAssertion < BasicAssertion
191
- MATCHERS = %i[
192
- assert_predicate
193
- assert_not_predicate
194
- refute_predicate
195
- ].freeze
196
-
197
- # @!method self.minitest_assertion(node)
198
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
199
- (send nil? {:assert_predicate :assert_not_predicate :refute_predicate} $_ ${sym} $_?)
200
- PATTERN
166
+ match_assertions :assert_predicate,
167
+ :assert_not_predicate,
168
+ :refute_predicate,
169
+ captures: '$_ ${sym} $_?'
201
170
 
202
171
  def self.match(subject, predicate, failure_message)
203
- return nil unless predicate.value.end_with?('?')
172
+ predicate_name = predicate.value.to_s
173
+ return nil unless predicate_name.end_with?('?')
174
+
175
+ matcher_name = predicate_name.delete_suffix('?')
176
+ return nil unless valid_matcher_name?(matcher_name)
204
177
 
205
- new(predicate, subject, failure_message.first)
178
+ new(predicate, subject, failure_message.first, matcher_name)
179
+ end
180
+
181
+ def self.valid_matcher_name?(matcher_name)
182
+ matcher_name.match?(/\A\w+\z/)
183
+ end
184
+
185
+ def initialize(expected, actual, failure_message, matcher_name)
186
+ super(expected, actual, failure_message)
187
+
188
+ @matcher_name = matcher_name
206
189
  end
207
190
 
208
191
  def assertion
209
- "be_#{expected.delete_prefix(':').delete_suffix('?')}"
192
+ "be_#{@matcher_name}"
210
193
  end
211
194
  end
212
195
 
213
196
  # :nodoc:
214
197
  class MatchAssertion < BasicAssertion
215
- MATCHERS = %i[
216
- assert_match
217
- refute_match
218
- ].freeze
219
-
220
- # @!method self.minitest_assertion(node)
221
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
222
- (send nil? {:assert_match :refute_match} $_ $_ $_?)
223
- PATTERN
224
-
225
- def self.match(matcher, actual, failure_message)
226
- new(matcher, actual, failure_message.first)
227
- end
198
+ match_assertions :assert_match,
199
+ :refute_match,
200
+ captures: '$_ $_ $_?'
228
201
 
229
202
  def assertion
230
203
  "match(#{expected})"
@@ -233,16 +206,10 @@ module RuboCop
233
206
 
234
207
  # :nodoc:
235
208
  class NilAssertion < BasicAssertion
236
- MATCHERS = %i[
237
- assert_nil
238
- assert_not_nil
239
- refute_nil
240
- ].freeze
241
-
242
- # @!method self.minitest_assertion(node)
243
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
244
- (send nil? {:assert_nil :assert_not_nil :refute_nil} $_ $_?)
245
- PATTERN
209
+ match_assertions :assert_nil,
210
+ :assert_not_nil,
211
+ :refute_nil,
212
+ captures: '$_ $_?'
246
213
 
247
214
  def self.match(actual, failure_message)
248
215
  new(nil, actual, failure_message.first)
@@ -255,16 +222,10 @@ module RuboCop
255
222
 
256
223
  # :nodoc:
257
224
  class EmptyAssertion < BasicAssertion
258
- MATCHERS = %i[
259
- assert_empty
260
- assert_not_empty
261
- refute_empty
262
- ].freeze
263
-
264
- # @!method self.minitest_assertion(node)
265
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
266
- (send nil? {:assert_empty :assert_not_empty :refute_empty} $_ $_?)
267
- PATTERN
225
+ match_assertions :assert_empty,
226
+ :assert_not_empty,
227
+ :refute_empty,
228
+ captures: '$_ $_?'
268
229
 
269
230
  def self.match(actual, failure_message)
270
231
  new(nil, actual, failure_message.first)
@@ -277,14 +238,7 @@ module RuboCop
277
238
 
278
239
  # :nodoc:
279
240
  class TrueAssertion < BasicAssertion
280
- MATCHERS = %i[
281
- assert_true
282
- ].freeze
283
-
284
- # @!method self.minitest_assertion(node)
285
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
286
- (send nil? {:assert_true} $_ $_?)
287
- PATTERN
241
+ match_assertions :assert_true, captures: '$_ $_?'
288
242
 
289
243
  def self.match(actual, failure_message)
290
244
  new(nil, actual, failure_message.first)
@@ -297,14 +251,7 @@ module RuboCop
297
251
 
298
252
  # :nodoc:
299
253
  class FalseAssertion < BasicAssertion
300
- MATCHERS = %i[
301
- assert_false
302
- ].freeze
303
-
304
- # @!method self.minitest_assertion(node)
305
- def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective
306
- (send nil? {:assert_false} $_ $_?)
307
- PATTERN
254
+ match_assertions :assert_false, captures: '$_ $_?'
308
255
 
309
256
  def self.match(actual, failure_message)
310
257
  new(nil, actual, failure_message.first)
@@ -315,6 +262,37 @@ module RuboCop
315
262
  end
316
263
  end
317
264
 
265
+ # :nodoc:
266
+ module ResponseAssertionActual
267
+ RESPONSE_NODE = Struct.new(:source).new('response')
268
+
269
+ def match(expected, failure_message)
270
+ new(expected, RESPONSE_NODE, failure_message.first)
271
+ end
272
+ end
273
+
274
+ # :nodoc:
275
+ class ResponseAssertion < BasicAssertion
276
+ extend ResponseAssertionActual
277
+
278
+ match_assertions :assert_response, captures: '$_ $_?'
279
+
280
+ def assertion
281
+ "have_http_status(#{expected})"
282
+ end
283
+ end
284
+
285
+ # :nodoc:
286
+ class RedirectAssertion < BasicAssertion
287
+ extend ResponseAssertionActual
288
+
289
+ match_assertions :assert_redirected_to, captures: '$_ $_?'
290
+
291
+ def assertion
292
+ "redirect_to(#{expected})"
293
+ end
294
+ end
295
+
318
296
  MSG = 'Use `%<prefer>s`.'
319
297
 
320
298
  # TODO: replace with `BasicAssertion.subclasses` in Ruby 3.1+
@@ -9,7 +9,7 @@ module RuboCop
9
9
  # This cop is unsafe because it cannot guarantee that
10
10
  # the test target is an instance of `ActiveModel::Validations``.
11
11
  #
12
- # @example EnforcedStyle: not_to (default)
12
+ # @example `EnforcedStyle: not_to` (default)
13
13
  # # bad
14
14
  # expect(foo).to be_invalid
15
15
  #
@@ -19,7 +19,7 @@ module RuboCop
19
19
  # # good (with method chain)
20
20
  # expect(foo).to be_invalid.and be_odd
21
21
  #
22
- # @example EnforcedStyle: be_invalid
22
+ # @example `EnforcedStyle: be_invalid`
23
23
  # # bad
24
24
  # expect(foo).not_to be_valid
25
25
  #
@@ -29,7 +29,7 @@ module RuboCop
29
29
  # # good (with method chain)
30
30
  # expect(foo).to be_invalid.or be_even
31
31
  #
32
- class NegationBeValid < ::RuboCop::Cop::Base
32
+ class NegationBeValid < RuboCop::Cop::Base
33
33
  extend AutoCorrector
34
34
  include ConfigurableEnforcedStyle
35
35
 
@@ -38,7 +38,7 @@ module RuboCop
38
38
 
39
39
  # @!method not_to?(node)
40
40
  def_node_matcher :not_to?, <<~PATTERN
41
- (send ... :not_to (send nil? :be_valid ...))
41
+ (send ... {:not_to :to_not} (send nil? :be_valid ...))
42
42
  PATTERN
43
43
 
44
44
  # @!method be_invalid?(node)
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpecRails
6
+ # Prefer `have_enqueued_job` over `receive(:perform_later)`.
7
+ #
8
+ # The `have_enqueued_job` matcher is preferred for testing ActiveJob
9
+ # enqueuing. It is more explicit and provides better clarity than
10
+ # using `receive(:perform_later)`.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # expect(MyJob).to receive(:perform_later)
15
+ # do_something
16
+ #
17
+ # # bad
18
+ # allow(MyJob).to receive(:perform_later)
19
+ # do_something
20
+ # expect(MyJob).to have_received(:perform_later)
21
+ #
22
+ # # bad
23
+ # expect(MyJob).to receive(:perform_later).with(user, order)
24
+ #
25
+ # # good
26
+ # expect { do_something }.to have_enqueued_job(MyJob)
27
+ #
28
+ # # good
29
+ # expect { do_something }.to have_enqueued_job(MyJob).with(user, order)
30
+ #
31
+ # # good
32
+ # expect { do_something }
33
+ # .to have_enqueued_job(MyJob)
34
+ # .on_queue('mailers')
35
+ # .at(Date.tomorrow.noon)
36
+ #
37
+ class ReceivePerformLater < RuboCop::Cop::Base
38
+ MSG = 'Prefer `expect { ... }.%<runner>s ' \
39
+ 'have_enqueued_job(%<job_class>s)` ' \
40
+ 'over `%<receiver>s(%<job_class>s).%<to>s ' \
41
+ '%<matcher>s(:perform_later)`.'
42
+
43
+ RESTRICT_ON_SEND = %i[receive have_received].to_set
44
+ RUNNERS = %i[to to_not not_to].freeze
45
+
46
+ # @!method receive_perform_later?(node)
47
+ def_node_matcher :receive_perform_later?, <<~PATTERN
48
+ (send nil? {:receive :have_received}
49
+ (sym :perform_later))
50
+ PATTERN
51
+
52
+ # @!method expect_or_allow?(node)
53
+ def_node_matcher :expect_or_allow?, <<~PATTERN
54
+ (send nil? {:expect :allow} {const_type? (send nil? :described_class)})
55
+ PATTERN
56
+
57
+ def on_send(node)
58
+ return unless receive_perform_later?(node)
59
+ return unless (runner_node = find_runner_node(node))
60
+ return unless runner_matcher?(node, runner_node)
61
+
62
+ register_offense(node, runner_node)
63
+ end
64
+
65
+ private
66
+
67
+ def register_offense(matcher_node, runner_node)
68
+ expect_node = runner_node.receiver
69
+ return unless expect_or_allow?(expect_node)
70
+ return if allow_receive_combination?(expect_node, matcher_node)
71
+
72
+ job_class = expect_node.first_argument
73
+ add_offense(runner_node,
74
+ message: offense_message(expect_node, job_class,
75
+ runner_node, matcher_node))
76
+ end
77
+
78
+ def allow_receive_combination?(expect_node, matcher_node)
79
+ expect_node.method?(:allow) && matcher_node.method?(:receive)
80
+ end
81
+
82
+ def offense_message(expect_node, job_class, runner_node, matcher_node)
83
+ format(MSG,
84
+ receiver: expect_node.method_name,
85
+ job_class: job_class.source,
86
+ runner: runner_node.method_name,
87
+ to: runner_node.method_name,
88
+ matcher: matcher_node.method_name)
89
+ end
90
+
91
+ def find_runner_node(node)
92
+ node.each_ancestor(:send).find { |ancestor| runner?(ancestor) }
93
+ end
94
+
95
+ def runner_matcher?(matcher_node, runner_node)
96
+ node = runner_node.first_argument
97
+ node = node.receiver while node&.send_type? && node != matcher_node
98
+ node == matcher_node
99
+ end
100
+
101
+ def runner?(node)
102
+ RUNNERS.include?(node.method_name)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -3,15 +3,26 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpecRails
6
- # Prefer to travel in `before` rather than `around`.
6
+ # Checks for time travel helpers in `around` hooks.
7
+ #
8
+ # In Rails example groups, `freeze_time` in a `before` hook does not need
9
+ # a block: Rails' `after_teardown` calls `travel_back` after each example.
10
+ # This also allows an example to use block-form time travel, which Rails
11
+ # does not allow inside another time travel block.
12
+ # See https://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html
7
13
  #
8
14
  # @safety
9
- # This cop is unsafe because the automatic `travel_back` is only run
10
- # on test cases that are considered as Rails related.
15
+ # The automatic `travel_back` requires both
16
+ # `ActiveSupport::Testing::TimeHelpers` and RSpec Rails' lifecycle
17
+ # hooks. RSpec Rails applies those hooks to example groups with Rails
18
+ # `type:` metadata. File paths set that metadata only when
19
+ # `infer_spec_type_from_file_location!` is enabled. In a plain RSpec
20
+ # group that only includes TimeHelpers, use a block or call
21
+ # `travel_back` explicitly.
22
+ # See https://rspec.info/features/7-1/rspec-rails/directory-structure/
11
23
  #
12
- # And also, this cop's autocorrection is unsafe because the order of
13
- # execution will change if other steps exist before traveling in
14
- # `around`.
24
+ # Autocorrection can change execution order: `around` starts before
25
+ # all `before` hooks, while `before` runs in normal hook order.
15
26
  #
16
27
  # @example
17
28
  # # bad
@@ -29,7 +40,7 @@ module RuboCop
29
40
  # # good
30
41
  # before { freeze_time }
31
42
  #
32
- class TravelAround < ::RuboCop::Cop::Base
43
+ class TravelAround < RuboCop::Cop::Base
33
44
  extend AutoCorrector
34
45
 
35
46
  MSG = 'Prefer to travel in `before` rather than `around`.'
@@ -45,7 +56,7 @@ module RuboCop
45
56
  (block
46
57
  $(send nil? TRAVEL_METHOD_NAMES ...)
47
58
  (args ...)
48
- (send _ :run)
59
+ (send (lvar _) :run)
49
60
  )
50
61
  PATTERN
51
62
 
@@ -64,7 +75,7 @@ module RuboCop
64
75
  )
65
76
  PATTERN
66
77
 
67
- def on_block(node)
78
+ def on_block(node) # rubocop:disable InternalAffairs/ItblockHandler
68
79
  extract_run_in_travel(node) do |run_node|
69
80
  run_in_travel(node, run_node)
70
81
  end
@@ -76,26 +87,30 @@ module RuboCop
76
87
 
77
88
  private
78
89
 
79
- def run_in_travel(node, run_node)
80
- around_node = extract_surrounding_around_block(run_node)
90
+ def run_in_travel(node, travel_node)
91
+ around_node = extract_surrounding_around_block(node)
81
92
  return unless around_node
93
+ return unless matching_run_receiver?(node.body, around_node)
82
94
 
83
95
  add_offense(node) do |corrector|
84
96
  corrector.replace(node, node.body.source)
85
- corrector.insert_before(around_node,
86
- "before { #{run_node.source} }\n\n")
97
+ corrector.insert_before(
98
+ around_node,
99
+ "before { #{travel_node.source} }\n\n#{indent(around_node)}"
100
+ )
87
101
  end
88
102
  end
89
103
 
90
104
  def travel_with_block_pass(node, lvar)
91
105
  around_node = extract_surrounding_around_block(node)
92
106
  return unless around_node
107
+ return unless lvar.name == around_argument_name(around_node)
93
108
 
94
109
  add_offense(node) do |corrector|
95
110
  corrector.replace(node, "#{lvar.name}.run")
96
111
  corrector.insert_before(
97
112
  around_node,
98
- "before { #{node.method_name} }\n\n"
113
+ "before { #{node.method_name} }\n\n#{indent(around_node)}"
99
114
  )
100
115
  end
101
116
  end
@@ -104,9 +119,23 @@ module RuboCop
104
119
  # @return [RuboCop::AST::BlockNode, nil]
105
120
  def extract_surrounding_around_block(node)
106
121
  node.each_ancestor(:block).find do |ancestor|
107
- match_around_each?(ancestor)
122
+ match_around_each?(ancestor) &&
123
+ direct_child_of_around_body?(node, ancestor)
108
124
  end
109
125
  end
126
+
127
+ def direct_child_of_around_body?(node, around_node)
128
+ node.parent == around_node ||
129
+ (node.parent.begin_type? && node.parent.parent == around_node)
130
+ end
131
+
132
+ def matching_run_receiver?(run_node, around_node)
133
+ run_node.receiver.children.first == around_argument_name(around_node)
134
+ end
135
+
136
+ def around_argument_name(around_node)
137
+ around_node.first_argument&.name
138
+ end
110
139
  end
111
140
  end
112
141
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Cops for the `RSpecRails` department. The department's cops are
6
+ # registered for lazy loading and their files are loaded on demand.
7
+ module RSpecRails
8
+ extend LazyLoader
9
+
10
+ register_cop :AvoidSetupHook, "#{__dir__}/rspec_rails/avoid_setup_hook"
11
+ register_cop :FileFixture, "#{__dir__}/rspec_rails/file_fixture"
12
+ register_cop :HaveHttpStatus, "#{__dir__}/rspec_rails/have_http_status"
13
+ register_cop :HttpStatus, "#{__dir__}/rspec_rails/http_status"
14
+ register_cop :HttpStatusNameConsistency, "#{__dir__}/rspec_rails/http_status_name_consistency"
15
+ register_cop :InferredSpecType, "#{__dir__}/rspec_rails/inferred_spec_type"
16
+ register_cop :MinitestAssertions, "#{__dir__}/rspec_rails/minitest_assertions"
17
+ register_cop :NegationBeValid, "#{__dir__}/rspec_rails/negation_be_valid"
18
+ register_cop :ReceivePerformLater, "#{__dir__}/rspec_rails/receive_perform_later"
19
+ register_cop :TravelAround, "#{__dir__}/rspec_rails/travel_around"
20
+ end
21
+ end
22
+ end
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'rspec_rails/avoid_setup_hook'
4
- require_relative 'rspec_rails/have_http_status'
5
- require_relative 'rspec_rails/http_status'
6
- require_relative 'rspec_rails/inferred_spec_type'
7
- require_relative 'rspec_rails/minitest_assertions'
8
- require_relative 'rspec_rails/negation_be_valid'
9
- require_relative 'rspec_rails/travel_around'
3
+ # @deprecated This file is deprecated. Cops are registered for lazy loading in
4
+ # `rubocop/cop/rspec_rails`; this file is kept for compatibility with code
5
+ # that requires it directly.
6
+ require_relative 'rspec_rails'
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module RSpecRails
5
5
  # Version information for the RSpec Rails RuboCop plugin.
6
6
  module Version
7
- STRING = '2.31.0'
7
+ STRING = '2.33.0'
8
8
  end
9
9
  end
10
10
  end
@@ -10,4 +10,4 @@ require_relative 'rubocop/rspec_rails/plugin'
10
10
  require_relative 'rubocop/rspec_rails/version'
11
11
 
12
12
  require 'rubocop/cop/rspec/base'
13
- require_relative 'rubocop/cop/rspec_rails_cops'
13
+ require_relative 'rubocop/cop/rspec_rails'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.31.0
4
+ version: 2.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Quorning
@@ -10,7 +10,7 @@ authors:
10
10
  - Yudai Takada
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2025-03-10 00:00:00.000000000 Z
13
+ date: 1980-01-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: lint_roller
@@ -32,20 +32,14 @@ dependencies:
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '1.72'
36
- - - ">="
37
- - !ruby/object:Gem::Version
38
- version: 1.72.1
35
+ version: '1.89'
39
36
  type: :runtime
40
37
  prerelease: false
41
38
  version_requirements: !ruby/object:Gem::Requirement
42
39
  requirements:
43
40
  - - "~>"
44
41
  - !ruby/object:Gem::Version
45
- version: '1.72'
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: 1.72.1
42
+ version: '1.89'
49
43
  - !ruby/object:Gem::Dependency
50
44
  name: rubocop-rspec
51
45
  requirement: !ruby/object:Gem::Requirement
@@ -75,12 +69,16 @@ files:
75
69
  - README.md
76
70
  - config/default.yml
77
71
  - lib/rubocop-rspec_rails.rb
72
+ - lib/rubocop/cop/rspec_rails.rb
78
73
  - lib/rubocop/cop/rspec_rails/avoid_setup_hook.rb
74
+ - lib/rubocop/cop/rspec_rails/file_fixture.rb
79
75
  - lib/rubocop/cop/rspec_rails/have_http_status.rb
80
76
  - lib/rubocop/cop/rspec_rails/http_status.rb
77
+ - lib/rubocop/cop/rspec_rails/http_status_name_consistency.rb
81
78
  - lib/rubocop/cop/rspec_rails/inferred_spec_type.rb
82
79
  - lib/rubocop/cop/rspec_rails/minitest_assertions.rb
83
80
  - lib/rubocop/cop/rspec_rails/negation_be_valid.rb
81
+ - lib/rubocop/cop/rspec_rails/receive_perform_later.rb
84
82
  - lib/rubocop/cop/rspec_rails/travel_around.rb
85
83
  - lib/rubocop/cop/rspec_rails_cops.rb
86
84
  - lib/rubocop/rspec_rails/config_formatter.rb
@@ -110,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
108
  - !ruby/object:Gem::Version
111
109
  version: '0'
112
110
  requirements: []
113
- rubygems_version: 3.6.2
111
+ rubygems_version: 4.0.20
114
112
  specification_version: 4
115
113
  summary: Code style checking for RSpec Rails files
116
114
  test_files: []