rubocop-rspec 2.10.0 → 2.12.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/config/default.yml +32 -3
  4. data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +1 -1
  5. data/lib/rubocop/cop/rspec/capybara/specific_matcher.rb +77 -0
  6. data/lib/rubocop/cop/rspec/change_by_zero.rb +93 -0
  7. data/lib/rubocop/cop/rspec/described_class.rb +13 -20
  8. data/lib/rubocop/cop/rspec/dialect.rb +1 -1
  9. data/lib/rubocop/cop/rspec/empty_hook.rb +2 -4
  10. data/lib/rubocop/cop/rspec/example_length.rb +1 -1
  11. data/lib/rubocop/cop/rspec/example_without_description.rb +1 -1
  12. data/lib/rubocop/cop/rspec/expect_actual.rb +2 -0
  13. data/lib/rubocop/cop/rspec/expect_change.rb +18 -12
  14. data/lib/rubocop/cop/rspec/expect_output.rb +1 -1
  15. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +32 -9
  16. data/lib/rubocop/cop/rspec/factory_bot/syntax_methods.rb +1 -1
  17. data/lib/rubocop/cop/rspec/file_path.rb +2 -1
  18. data/lib/rubocop/cop/rspec/focus.rb +2 -4
  19. data/lib/rubocop/cop/rspec/hook_argument.rb +3 -3
  20. data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -1
  21. data/lib/rubocop/cop/rspec/it_behaves_like.rb +2 -2
  22. data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +1 -1
  23. data/lib/rubocop/cop/rspec/message_expectation.rb +1 -1
  24. data/lib/rubocop/cop/rspec/message_spies.rb +7 -1
  25. data/lib/rubocop/cop/rspec/mixin/empty_line_separation.rb +13 -4
  26. data/lib/rubocop/cop/rspec/multiple_expectations.rb +20 -0
  27. data/lib/rubocop/cop/rspec/not_to_not.rb +14 -1
  28. data/lib/rubocop/cop/rspec/rails/have_http_status.rb +47 -0
  29. data/lib/rubocop/cop/rspec/return_from_stub.rb +11 -11
  30. data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
  31. data/lib/rubocop/cop/rspec/variable_definition.rb +1 -1
  32. data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
  33. data/lib/rubocop/cop/rspec/yield.rb +2 -2
  34. data/lib/rubocop/cop/rspec_cops.rb +3 -0
  35. data/lib/rubocop/rspec/config_formatter.rb +3 -0
  36. data/lib/rubocop/rspec/node.rb +1 -1
  37. data/lib/rubocop/rspec/version.rb +1 -1
  38. metadata +9 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d0bedaa464141123a49b02ad1a31ed8a63b9960304014c0ef5e52f96fb78176
4
- data.tar.gz: e310236f596a19629629c70d9f94fcb46a39183c43908b5864860efb2abd7602
3
+ metadata.gz: 06d6fd83af093abc4da74f5791334c364b86c8238610e53890f4b197f97ce1b6
4
+ data.tar.gz: 3e40ac4c4e15bee0892061da115755ad8a9cc872218b8cf2d8fe166ea40c6f83
5
5
  SHA512:
6
- metadata.gz: 7cd82a374f1cd9362070fe6561f9c04927a2ac33f5e1b5ee97a80bc443b0a4c3c90a75d93778e7bf6f439ff759b60857cdeccc2a7b51bfdc8feebccc519e36c8
7
- data.tar.gz: 19bbbdd2d38ef4802be62f44a18e95e83caaf6899c654dff281fe7058fc9bdf6f776cf0491b825b274f67450388a7aef292c2ee51033f6ae96a9d8671829c5e4
6
+ metadata.gz: d84bfa56ac9503ad57e0dea9e5207469a3acf8d086e1ef0bf3f8239a9a704f4ce40e7ce82e10596699d948217ff55347098e0421af042e3653e6e3ea0b7e3593
7
+ data.tar.gz: c643ac0b7e06972fb90347dff8684b4c94e08ca3e9a85a5406bf87c3ce6f88f4395e878dce7fae224049127cc53dcb4639e6fb5d5d6134da9fd4dff6013480ca
data/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 2.12.0 (2022-07-02)
6
+
7
+ * Fix incorrect path suggested by `RSpec/FilePath` cop when second argument contains spaces. ([@tejasbubane][])
8
+ * Fix autocorrect for EmptyLineSeparation. ([@johnny-miyake][])
9
+ * Add new `RSpec/Capybara/SpecificMatcher` cop. ([@ydah][])
10
+ * Fixed false offense detection in `FactoryBot/CreateList` when a n.times block is including method calls in the factory create arguments. ([@ngouy][])
11
+ * Fix error in `RSpec/RSpec/FactoryBot/CreateList` cop for empty block. ([@tejasbubane][])
12
+ * Update `RSpec/MultipleExpectations` cop documentation with examples of aggregate_failures use. ([@edgibbs][])
13
+ * Declare autocorrect as unsafe for `RSpec/VerifiedDoubleReference`. ([@Drowze][])
14
+ * Add new `RSpec/Rails/HaveHttpStatus` cop. ([@akiomik][])
15
+
16
+ ## 2.11.1 (2022-05-18)
17
+
18
+ * Fix a regression in `RSpec/ExpectChange` flagging chained method calls. ([@pirj][])
19
+
20
+ ## 2.11.0 (2022-05-18)
21
+
22
+ * Drop Ruby 2.5 support. ([@ydah][])
23
+ * Add new `RSpec/ChangeByZero` cop. ([@ydah][])
24
+ * Improve `RSpec/ExpectChange` to detect namespaced and top-level constants. ([@M-Yamashita01][])
25
+ * Introduce an amendment to `Metrics/BlockLength` to exclude spec files. ([@luke-hill][])
26
+
5
27
  ## 2.10.0 (2022-04-19)
6
28
 
7
29
  * Fix a false positive for `RSpec/EmptyExampleGroup` when expectations in case statement. ([@ydah][])
@@ -681,3 +703,10 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
681
703
  [@oshiro3]: https://github.com/oshiro3
682
704
  [@ydah]: https://github.com/ydah
683
705
  [@t3h2mas]: https://github.com/t3h2mas
706
+ [@M-Yamashita01]: https://github.com/M-Yamashita01
707
+ [@luke-hill]: https://github.com/luke-hill
708
+ [@johnny-miyake]: https://github.com/johnny-miyake
709
+ [@ngouy]: https://github.com/ngouy
710
+ [@edgibbs]: https://github.com/edgibbs
711
+ [@Drowze]: https://github.com/Drowze
712
+ [@akiomik]: https://github.com/akiomik
data/config/default.yml CHANGED
@@ -110,6 +110,14 @@ RSpec:
110
110
  - subject
111
111
  - subject!
112
112
 
113
+ Metrics/BlockLength:
114
+ inherit_mode:
115
+ merge:
116
+ - Exclude
117
+ Exclude:
118
+ - "**/*_spec.rb"
119
+ - "**/spec/**/*"
120
+
113
121
  RSpec/AlignLeftLetBrace:
114
122
  Description: Checks that left braces for adjacent single line lets are aligned.
115
123
  Enabled: false
@@ -176,6 +184,12 @@ RSpec/BeforeAfterAll:
176
184
  StyleGuide: https://rspec.rubystyle.guide/#avoid-hooks-with-context-scope
177
185
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeforeAfterAll
178
186
 
187
+ RSpec/ChangeByZero:
188
+ Description: Prefer negated matchers over `to change.by(0)`.
189
+ Enabled: pending
190
+ VersionAdded: 2.11.0
191
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ChangeByZero
192
+
179
193
  RSpec/ContextMethod:
180
194
  Description: "`context` should not be used for specifying methods."
181
195
  Enabled: true
@@ -256,7 +270,7 @@ RSpec/DescribedClassModuleWrapping:
256
270
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribedClassModuleWrapping
257
271
 
258
272
  RSpec/Dialect:
259
- Description: This cop enforces custom RSpec dialects.
273
+ Description: Enforces custom RSpec dialects.
260
274
  Enabled: false
261
275
  PreferredMethods: {}
262
276
  VersionAdded: '1.33'
@@ -769,11 +783,13 @@ RSpec/VariableName:
769
783
  RSpec/VerifiedDoubleReference:
770
784
  Description: Checks for consistent verified double reference style.
771
785
  Enabled: pending
786
+ SafeAutoCorrect: false
772
787
  EnforcedStyle: constant
773
788
  SupportedStyles:
774
789
  - constant
775
790
  - string
776
791
  VersionAdded: 2.10.0
792
+ VersionChanged: '2.12'
777
793
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubleReference
778
794
 
779
795
  RSpec/VerifiedDoubles:
@@ -787,13 +803,13 @@ RSpec/VerifiedDoubles:
787
803
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubles
788
804
 
789
805
  RSpec/VoidExpect:
790
- Description: This cop checks void `expect()`.
806
+ Description: Checks void `expect()`.
791
807
  Enabled: true
792
808
  VersionAdded: '1.16'
793
809
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VoidExpect
794
810
 
795
811
  RSpec/Yield:
796
- Description: This cop checks for calling a block within a stub.
812
+ Description: Checks for calling a block within a stub.
797
813
  Enabled: true
798
814
  VersionAdded: '1.32'
799
815
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Yield
@@ -818,6 +834,12 @@ RSpec/Capybara/FeatureMethods:
818
834
  VersionChanged: '2.0'
819
835
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods
820
836
 
837
+ RSpec/Capybara/SpecificMatcher:
838
+ Description: Checks for there is a more specific matcher offered by Capybara.
839
+ Enabled: pending
840
+ VersionAdded: '2.12'
841
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/SpecificMatcher
842
+
821
843
  RSpec/Capybara/VisibilityMatcher:
822
844
  Description: Checks for boolean visibility in Capybara finders.
823
845
  Enabled: true
@@ -887,6 +909,13 @@ RSpec/Rails/AvoidSetupHook:
887
909
  VersionAdded: '2.4'
888
910
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/AvoidSetupHook
889
911
 
912
+ RSpec/Rails/HaveHttpStatus:
913
+ Description: Checks that tests use `have_http_status` instead of equality matchers.
914
+ Enabled: pending
915
+ SafeAutoCorrect: false
916
+ VersionAdded: '2.12'
917
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HaveHttpStatus
918
+
890
919
  RSpec/Rails/HttpStatus:
891
920
  Description: Enforces use of symbolic or numeric value to describe HTTP status.
892
921
  Enabled: true
@@ -46,7 +46,7 @@ module RuboCop
46
46
 
47
47
  MSG = 'Use `%<replacement>s` instead of `%<method>s`.'
48
48
 
49
- # https://git.io/v7Kwr
49
+ # https://github.com/teamcapybara/capybara/blob/e283c1aeaa72441f5403963577e16333bf111a81/lib/capybara/rspec/features.rb#L31-L36
50
50
  MAP = {
51
51
  background: :before,
52
52
  scenario: :it,
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ module Capybara
7
+ # Checks for there is a more specific matcher offered by Capybara.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ # expect(page).to have_selector('button')
13
+ # expect(page).to have_no_selector('button.cls')
14
+ # expect(page).to have_css('button')
15
+ # expect(page).to have_no_css('a.cls', exact_text: 'foo')
16
+ # expect(page).to have_css('table.cls')
17
+ # expect(page).to have_css('select')
18
+ #
19
+ # # good
20
+ # expect(page).to have_button
21
+ # expect(page).to have_no_button(class: 'cls')
22
+ # expect(page).to have_button
23
+ # expect(page).to have_no_link('foo', class: 'cls')
24
+ # expect(page).to have_table(class: 'cls')
25
+ # expect(page).to have_select
26
+ #
27
+ class SpecificMatcher < Base
28
+ MSG = 'Prefer `%<good_matcher>s` over `%<bad_matcher>s`.'
29
+ RESTRICT_ON_SEND = %i[have_selector have_no_selector have_css
30
+ have_no_css].freeze
31
+ SPECIFIC_MATCHER = {
32
+ 'button' => 'button',
33
+ 'a' => 'link',
34
+ 'table' => 'table',
35
+ 'select' => 'select'
36
+ }.freeze
37
+
38
+ # @!method first_argument(node)
39
+ def_node_matcher :first_argument, <<-PATTERN
40
+ (send nil? _ (str $_) ... )
41
+ PATTERN
42
+
43
+ def on_send(node)
44
+ return unless (arg = first_argument(node))
45
+ return unless (matcher = specific_matcher(arg))
46
+ return if acceptable_pattern?(arg)
47
+
48
+ add_offense(node, message: message(node, matcher))
49
+ end
50
+
51
+ private
52
+
53
+ def specific_matcher(arg)
54
+ splitted_arg = arg[/^\w+/, 0]
55
+ SPECIFIC_MATCHER[splitted_arg]
56
+ end
57
+
58
+ def acceptable_pattern?(arg)
59
+ arg.match?(/\[.+=\w+\]/)
60
+ end
61
+
62
+ def message(node, matcher)
63
+ format(MSG,
64
+ good_matcher: good_matcher(node, matcher),
65
+ bad_matcher: node.method_name)
66
+ end
67
+
68
+ def good_matcher(node, matcher)
69
+ node.method_name
70
+ .to_s
71
+ .gsub(/selector|css/, matcher.to_s)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Prefer negated matchers over `to change.by(0)`.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # expect { run }.to change(Foo, :bar).by(0)
11
+ # expect { run }.to change { Foo.bar }.by(0)
12
+ #
13
+ # # bad - compound expectations
14
+ # expect { run }
15
+ # .to change(Foo, :bar).by(0)
16
+ # .and change(Foo, :baz).by(0)
17
+ # expect { run }
18
+ # .to change { Foo.bar }.by(0)
19
+ # .and change { Foo.baz }.by(0)
20
+ #
21
+ # # good
22
+ # expect { run }.not_to change(Foo, :bar)
23
+ # expect { run }.not_to change { Foo.bar }
24
+ #
25
+ # # good - compound expectations
26
+ # define_negated_matcher :not_change, :change
27
+ # expect { run }
28
+ # .to not_change(Foo, :bar)
29
+ # .and not_change(Foo, :baz)
30
+ # expect { run }
31
+ # .to not_change { Foo.bar }
32
+ # .and not_change { Foo.baz }
33
+ #
34
+ class ChangeByZero < Base
35
+ extend AutoCorrector
36
+ MSG = 'Prefer `not_to change` over `to change.by(0)`.'
37
+ MSG_COMPOUND = 'Prefer negated matchers with compound expectations ' \
38
+ 'over `change.by(0)`.'
39
+ RESTRICT_ON_SEND = %i[change].freeze
40
+
41
+ # @!method expect_change_with_arguments(node)
42
+ def_node_matcher :expect_change_with_arguments, <<-PATTERN
43
+ (send
44
+ (send nil? :change ...) :by
45
+ (int 0))
46
+ PATTERN
47
+
48
+ # @!method expect_change_with_block(node)
49
+ def_node_matcher :expect_change_with_block, <<-PATTERN
50
+ (send
51
+ (block
52
+ (send nil? :change)
53
+ (args)
54
+ (send (...) $_)) :by
55
+ (int 0))
56
+ PATTERN
57
+
58
+ def on_send(node)
59
+ expect_change_with_arguments(node.parent) do
60
+ check_offense(node.parent)
61
+ end
62
+
63
+ expect_change_with_block(node.parent.parent) do
64
+ check_offense(node.parent.parent)
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def check_offense(node)
71
+ expression = node.loc.expression
72
+ if compound_expectations?(node)
73
+ add_offense(expression, message: MSG_COMPOUND)
74
+ else
75
+ add_offense(expression) do |corrector|
76
+ autocorrect(corrector, node)
77
+ end
78
+ end
79
+ end
80
+
81
+ def compound_expectations?(node)
82
+ %i[and or].include?(node.parent.method_name)
83
+ end
84
+
85
+ def autocorrect(corrector, node)
86
+ corrector.replace(node.parent.loc.selector, 'not_to')
87
+ range = node.loc.dot.with(end_pos: node.loc.expression.end_pos)
88
+ corrector.remove(range)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -11,7 +11,7 @@ module RuboCop
11
11
  # This cop can be configured using the `EnforcedStyle` and `SkipBlocks`
12
12
  # options.
13
13
  #
14
- # @example `EnforcedStyle: described_class`
14
+ # @example `EnforcedStyle: described_class` (default)
15
15
  # # bad
16
16
  # describe MyClass do
17
17
  # subject { MyClass.do_something }
@@ -78,9 +78,8 @@ module RuboCop
78
78
  PATTERN
79
79
 
80
80
  # @!method contains_described_class?(node)
81
- def_node_search :contains_described_class?, <<-PATTERN
82
- (send nil? :described_class)
83
- PATTERN
81
+ def_node_search :contains_described_class?,
82
+ '(send nil? :described_class)'
84
83
 
85
84
  def on_block(node)
86
85
  # In case the explicit style is used, we need to remember what's
@@ -129,17 +128,13 @@ module RuboCop
129
128
  end
130
129
 
131
130
  def scope_change?(node)
132
- scope_changing_syntax?(node) ||
131
+ scope_changing_syntax?(node) ||
133
132
  common_instance_exec_closure?(node) ||
134
133
  skippable_block?(node)
135
134
  end
136
135
 
137
136
  def skippable_block?(node)
138
- node.block_type? && !rspec_block?(node) && skip_blocks?
139
- end
140
-
141
- def skip_blocks?
142
- cop_config['SkipBlocks']
137
+ node.block_type? && !rspec_block?(node) && cop_config['SkipBlocks']
143
138
  end
144
139
 
145
140
  def offensive?(node)
@@ -152,6 +147,7 @@ module RuboCop
152
147
 
153
148
  def offensive_described_class?(node)
154
149
  return unless node.const_type?
150
+
155
151
  # E.g. `described_class::CONSTANT`
156
152
  return if contains_described_class?(node)
157
153
 
@@ -172,14 +168,13 @@ module RuboCop
172
168
  # @return [Array<Symbol>]
173
169
  # @example
174
170
  # # nil represents base constant
175
- # collapse_namespace([], :C) # => [:C]
176
- # collapse_namespace([:A, :B], [:C) # => [:A, :B, :C]
177
- # collapse_namespace([:A, :B], [:B, :C) # => [:A, :B, :C]
178
- # collapse_namespace([:A, :B], [nil, :C) # => [nil, :C]
179
- # collapse_namespace([:A, :B], [nil, :B, :C) # => [nil, :B, :C]
171
+ # collapse_namespace([], [:C]) # => [:C]
172
+ # collapse_namespace([:A, :B], [:C]) # => [:A, :B, :C]
173
+ # collapse_namespace([:A, :B], [:B, :C]) # => [:A, :B, :C]
174
+ # collapse_namespace([:A, :B], [nil, :C]) # => [nil, :C]
175
+ # collapse_namespace([:A, :B], [nil, :B, :C]) # => [nil, :B, :C]
180
176
  def collapse_namespace(namespace, const)
181
- return const if namespace.empty?
182
- return const if const.first.nil?
177
+ return const if namespace.empty? || const.first.nil?
183
178
 
184
179
  start = [0, (namespace.length - const.length)].max
185
180
  max = namespace.length
@@ -196,9 +191,7 @@ module RuboCop
196
191
  # const_name(s(:const, s(:const, nil, :M), :C)) # => [:M, :C]
197
192
  # const_name(s(:const, s(:cbase), :C)) # => [nil, :C]
198
193
  def const_name(node)
199
- # rubocop:disable InternalAffairs/NodeDestructuring
200
- namespace, name = *node
201
- # rubocop:enable InternalAffairs/NodeDestructuring
194
+ namespace, name = *node # rubocop:disable InternalAffairs/NodeDestructuring
202
195
  if !namespace
203
196
  [name]
204
197
  elsif namespace.const_type?
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpec
6
- # This cop enforces custom RSpec dialects.
6
+ # Enforces custom RSpec dialects.
7
7
  #
8
8
  # A dialect can be based on the following RSpec methods:
9
9
  #
@@ -36,11 +36,9 @@ module RuboCop
36
36
  def on_block(node)
37
37
  empty_hook?(node) do |hook|
38
38
  add_offense(hook) do |corrector|
39
- range = range_with_surrounding_space(
40
- range: node.loc.expression,
41
- side: :left
39
+ corrector.remove(
40
+ range_with_surrounding_space(node.loc.expression, side: :left)
42
41
  )
43
- corrector.remove(range)
44
42
  end
45
43
  end
46
44
  end
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # Checks for long examples.
7
7
  #
8
8
  # A long example is usually more difficult to understand. Consider
9
- # extracting out some behaviour, e.g. with a `let` block, or a helper
9
+ # extracting out some behavior, e.g. with a `let` block, or a helper
10
10
  # method.
11
11
  #
12
12
  # @example
@@ -14,7 +14,7 @@ module RuboCop
14
14
  #
15
15
  # This cop can be configured using the `EnforcedStyle` option
16
16
  #
17
- # @example `EnforcedStyle: always_allow`
17
+ # @example `EnforcedStyle: always_allow` (default)
18
18
  # # bad
19
19
  # it('') { is_expected.to be_good }
20
20
  # it '' do
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module RSpec
6
6
  # Checks for `expect(...)` calls containing literal values.
7
7
  #
8
+ # Autocorrection is performed when the expected is not a literal.
9
+ #
8
10
  # @example
9
11
  # # bad
10
12
  # expect(5).to eq(price)
@@ -10,14 +10,7 @@ module RuboCop
10
10
  #
11
11
  # This cop can be configured using the `EnforcedStyle` option.
12
12
  #
13
- # @example `EnforcedStyle: block`
14
- # # bad
15
- # expect { run }.to change(Foo, :bar)
16
- #
17
- # # good
18
- # expect { run }.to change { Foo.bar }
19
- #
20
- # @example `EnforcedStyle: method_call`
13
+ # @example `EnforcedStyle: method_call` (default)
21
14
  # # bad
22
15
  # expect { run }.to change { Foo.bar }
23
16
  # expect { run }.to change { foo.baz }
@@ -29,6 +22,13 @@ module RuboCop
29
22
  # expect { run }.to change { Foo.bar(:count) }
30
23
  # expect { run }.to change { user.reload.name }
31
24
  #
25
+ # @example `EnforcedStyle: block`
26
+ # # bad
27
+ # expect { run }.to change(Foo, :bar)
28
+ #
29
+ # # good
30
+ # expect { run }.to change { Foo.bar }
31
+ #
32
32
  class ExpectChange < Base
33
33
  extend AutoCorrector
34
34
  include ConfigurableEnforcedStyle
@@ -39,7 +39,7 @@ module RuboCop
39
39
 
40
40
  # @!method expect_change_with_arguments(node)
41
41
  def_node_matcher :expect_change_with_arguments, <<-PATTERN
42
- (send nil? :change $_ (sym $_))
42
+ (send nil? :change $_ ({sym str} $_))
43
43
  PATTERN
44
44
 
45
45
  # @!method expect_change_with_block(node)
@@ -47,7 +47,13 @@ module RuboCop
47
47
  (block
48
48
  (send nil? :change)
49
49
  (args)
50
- (send ({const send} nil? $_) $_)
50
+ (send
51
+ ${
52
+ (send nil? _) # change { user.name }
53
+ const # change { User.count }
54
+ }
55
+ $_
56
+ )
51
57
  )
52
58
  PATTERN
53
59
 
@@ -67,9 +73,9 @@ module RuboCop
67
73
  return unless style == :method_call
68
74
 
69
75
  expect_change_with_block(node) do |receiver, message|
70
- msg = format(MSG_BLOCK, obj: receiver, attr: message)
76
+ msg = format(MSG_BLOCK, obj: receiver.source, attr: message)
71
77
  add_offense(node, message: msg) do |corrector|
72
- replacement = "change(#{receiver}, :#{message})"
78
+ replacement = "change(#{receiver.source}, :#{message})"
73
79
  corrector.replace(node, replacement)
74
80
  end
75
81
  end
@@ -24,7 +24,7 @@ module RuboCop
24
24
  # rubocop:disable InternalAffairs/NodeDestructuring
25
25
  variable_name, _rhs = *node
26
26
  # rubocop:enable InternalAffairs/NodeDestructuring
27
- name = variable_name[1..-1]
27
+ name = variable_name[1..]
28
28
  return unless name.eql?('stdout') || name.eql?('stderr')
29
29
 
30
30
  add_offense(node.loc.name, message: format(MSG, name: name))
@@ -8,15 +8,21 @@ module RuboCop
8
8
  #
9
9
  # This cop can be configured using the `EnforcedStyle` option
10
10
  #
11
- # @example `EnforcedStyle: create_list`
11
+ # @example `EnforcedStyle: create_list` (default)
12
12
  # # bad
13
13
  # 3.times { create :user }
14
14
  #
15
15
  # # good
16
16
  # create_list :user, 3
17
17
  #
18
- # # good
19
- # 3.times { |n| create :user, created_at: n.months.ago }
18
+ # # bad
19
+ # 3.times { create :user, age: 18 }
20
+ #
21
+ # # good - index is used to alter the created models attributes
22
+ # 3.times { |n| create :user, age: n }
23
+ #
24
+ # # good - contains a method call, may return different values
25
+ # 3.times { create :user, age: rand }
20
26
  #
21
27
  # @example `EnforcedStyle: n_times`
22
28
  # # bad
@@ -33,15 +39,28 @@ module RuboCop
33
39
  MSG_N_TIMES = 'Prefer %<number>s.times.'
34
40
  RESTRICT_ON_SEND = %i[create_list].freeze
35
41
 
36
- # @!method n_times_block_without_arg?(node)
37
- def_node_matcher :n_times_block_without_arg?, <<-PATTERN
42
+ # @!method n_times_block?(node)
43
+ def_node_matcher :n_times_block?, <<-PATTERN
38
44
  (block
39
45
  (send (int _) :times)
40
- (args)
41
46
  ...
42
47
  )
43
48
  PATTERN
44
49
 
50
+ # @!method n_times_block_with_arg_and_used?(node)
51
+ def_node_matcher :n_times_block_with_arg_and_used?, <<-PATTERN
52
+ (block
53
+ (send (int _) :times)
54
+ (args (arg _value))
55
+ `_value
56
+ )
57
+ PATTERN
58
+
59
+ # @!method arguments_include_method_call?(node)
60
+ def_node_matcher :arguments_include_method_call?, <<-PATTERN
61
+ (send ${nil? #factory_bot?} :create (sym $_) `$(send ...))
62
+ PATTERN
63
+
45
64
  # @!method factory_call(node)
46
65
  def_node_matcher :factory_call, <<-PATTERN
47
66
  (send ${nil? #factory_bot?} :create (sym $_) $...)
@@ -54,7 +73,11 @@ module RuboCop
54
73
 
55
74
  def on_block(node)
56
75
  return unless style == :create_list
57
- return unless n_times_block_without_arg?(node)
76
+
77
+ return unless n_times_block?(node)
78
+ return if n_times_block_with_arg_and_used?(node)
79
+ return unless node.body
80
+ return if arguments_include_method_call?(node.body)
58
81
  return unless contains_only_factory?(node.body)
59
82
 
60
83
  add_offense(node.send_node, message: MSG_CREATE_LIST) do |corrector|
@@ -193,7 +216,7 @@ module RuboCop
193
216
  if node.body.begin_type?
194
217
  format_multiline_block(node)
195
218
  else
196
- format_singeline_block(node)
219
+ format_singleline_block(node)
197
220
  end
198
221
  end
199
222
 
@@ -205,7 +228,7 @@ module RuboCop
205
228
  "#{indent_end}end"
206
229
  end
207
230
 
208
- def format_singeline_block(node)
231
+ def format_singleline_block(node)
209
232
  " { #{node.arguments.source} #{node.body.source} }"
210
233
  end
211
234
  end
@@ -7,7 +7,7 @@ module RuboCop
7
7
  # Use shorthands from `FactoryBot::Syntax::Methods` in your specs.
8
8
  #
9
9
  # @safety
10
- # The auto-correction is marked as unsafe because the cop
10
+ # The autocorrection is marked as unsafe because the cop
11
11
  # cannot verify whether you already include
12
12
  # `FactoryBot::Syntax::Methods` in your test suite.
13
13
  #
@@ -117,8 +117,9 @@ module RuboCop
117
117
 
118
118
  def name_pattern(method_name)
119
119
  return unless method_name&.str_type?
120
+ return if ignore_methods?
120
121
 
121
- ".*#{method_name.str_content.gsub(/\W/, '')}" unless ignore_methods?
122
+ ".*#{method_name.str_content.gsub(/\s/, '_').gsub(/\W/, '')}"
122
123
  end
123
124
 
124
125
  def expected_path(constant)
@@ -69,10 +69,8 @@ module RuboCop
69
69
  end
70
70
 
71
71
  def with_surrounding(focus)
72
- range_with_space = range_with_surrounding_space(
73
- range: focus.loc.expression,
74
- side: :left
75
- )
72
+ range_with_space =
73
+ range_with_surrounding_space(focus.loc.expression, side: :left)
76
74
 
77
75
  range_with_surrounding_comma(range_with_space, :left)
78
76
  end
@@ -10,7 +10,7 @@ module RuboCop
10
10
  # styles: "implicit", "each", and "example." All styles have
11
11
  # the same behavior.
12
12
  #
13
- # @example when configuration is `EnforcedStyle: implicit`
13
+ # @example `EnforcedStyle: implicit` (default)
14
14
  # # bad
15
15
  # before(:each) do
16
16
  # # ...
@@ -26,7 +26,7 @@ module RuboCop
26
26
  # # ...
27
27
  # end
28
28
  #
29
- # @example when configuration is `EnforcedStyle: each`
29
+ # @example `EnforcedStyle: each`
30
30
  # # bad
31
31
  # before(:example) do
32
32
  # # ...
@@ -42,7 +42,7 @@ module RuboCop
42
42
  # # ...
43
43
  # end
44
44
  #
45
- # @example when configuration is `EnforcedStyle: example`
45
+ # @example `EnforcedStyle: example`
46
46
  # # bad
47
47
  # before(:each) do
48
48
  # # ...
@@ -8,7 +8,7 @@ module RuboCop
8
8
  # This cop can be configured using the `EnforcedStyle` option
9
9
  # and supports the `--auto-gen-config` flag.
10
10
  #
11
- # @example `EnforcedStyle: is_expected`
11
+ # @example `EnforcedStyle: is_expected` (default)
12
12
  #
13
13
  # # bad
14
14
  # it { should be_truthy }
@@ -5,14 +5,14 @@ module RuboCop
5
5
  module RSpec
6
6
  # Checks that only one `it_behaves_like` style is used.
7
7
  #
8
- # @example when configuration is `EnforcedStyle: it_behaves_like`
8
+ # @example `EnforcedStyle: it_behaves_like` (default)
9
9
  # # bad
10
10
  # it_should_behave_like 'a foo'
11
11
  #
12
12
  # # good
13
13
  # it_behaves_like 'a foo'
14
14
  #
15
- # @example when configuration is `EnforcedStyle: it_should_behave_like`
15
+ # @example `EnforcedStyle: it_should_behave_like`
16
16
  # # bad
17
17
  # it_behaves_like 'a foo'
18
18
  #
@@ -10,7 +10,7 @@ module RuboCop
10
10
  #
11
11
  # If several examples may define a `DummyClass`, instead of being a
12
12
  # blank slate class as it will be in the first example, subsequent
13
- # examples will be reopening it and modifying its behaviour in
13
+ # examples will be reopening it and modifying its behavior in
14
14
  # unpredictable ways.
15
15
  # Even worse when a class that exists in the codebase is reopened.
16
16
  #
@@ -8,7 +8,7 @@ module RuboCop
8
8
  # This cop can be configured in your configuration using the
9
9
  # `EnforcedStyle` option and supports `--auto-gen-config`.
10
10
  #
11
- # @example `EnforcedStyle: allow`
11
+ # @example `EnforcedStyle: allow` (default)
12
12
  #
13
13
  # # bad
14
14
  # expect(foo).to receive(:bar)
@@ -8,21 +8,27 @@ module RuboCop
8
8
  # This cop can be configured in your configuration using the
9
9
  # `EnforcedStyle` option and supports `--auto-gen-config`.
10
10
  #
11
- # @example `EnforcedStyle: have_received`
11
+ # @example `EnforcedStyle: have_received` (default)
12
12
  #
13
13
  # # bad
14
14
  # expect(foo).to receive(:bar)
15
+ # do_something
15
16
  #
16
17
  # # good
18
+ # allow(foo).to receive(:bar) # or use instance_spy
19
+ # do_something
17
20
  # expect(foo).to have_received(:bar)
18
21
  #
19
22
  # @example `EnforcedStyle: receive`
20
23
  #
21
24
  # # bad
25
+ # allow(foo).to receive(:bar)
26
+ # do_something
22
27
  # expect(foo).to have_received(:bar)
23
28
  #
24
29
  # # good
25
30
  # expect(foo).to receive(:bar)
31
+ # do_something
26
32
  #
27
33
  class MessageSpies < Base
28
34
  include ConfigurableEnforcedStyle
@@ -4,7 +4,10 @@ module RuboCop
4
4
  module Cop
5
5
  module RSpec
6
6
  # Helps determine the offending location if there is not an empty line
7
- # following the node. Allows comments to follow directly after.
7
+ # following the node. Allows comments to follow directly after
8
+ # in the following cases.
9
+ # - `rubocop:enable` directive
10
+ # - followed by empty line(s)
8
11
  module EmptyLineSeparation
9
12
  include FinalEndLocation
10
13
  include RangeHelp
@@ -21,13 +24,19 @@ module RuboCop
21
24
  end
22
25
 
23
26
  def missing_separating_line(node)
24
- line = final_end_location(node).line
27
+ line = final_end_line = final_end_location(node).line
25
28
 
26
- line += 1 while comment_line?(processed_source[line])
29
+ while comment_line?(processed_source[line])
30
+ line += 1
31
+ comment = processed_source.comment_at_line(line)
32
+ if DirectiveComment.new(comment).enabled?
33
+ enable_directive_line = line
34
+ end
35
+ end
27
36
 
28
37
  return if processed_source[line].blank?
29
38
 
30
- yield offending_loc(line)
39
+ yield offending_loc(enable_directive_line || final_end_line)
31
40
  end
32
41
 
33
42
  def offending_loc(last_line)
@@ -31,6 +31,26 @@ module RuboCop
31
31
  # end
32
32
  # end
33
33
  #
34
+ # @example `aggregate_failures: true` (default)
35
+ #
36
+ # # good - the cop ignores when RSpec aggregates failures
37
+ # describe UserCreator do
38
+ # it 'builds a user', :aggregate_failures do
39
+ # expect(user.name).to eq("John")
40
+ # expect(user.age).to eq(22)
41
+ # end
42
+ # end
43
+ #
44
+ # @example `aggregate_failures: false`
45
+ #
46
+ # # Detected as an offense
47
+ # describe UserCreator do
48
+ # it 'builds a user', aggregate_failures: false do
49
+ # expect(user.name).to eq("John")
50
+ # expect(user.age).to eq(22)
51
+ # end
52
+ # end
53
+ #
34
54
  # @example configuration
35
55
  #
36
56
  # # .rubocop.yml
@@ -5,7 +5,8 @@ module RuboCop
5
5
  module RSpec
6
6
  # Checks for consistent method usage for negating expectations.
7
7
  #
8
- # @example
8
+ # @example `EnforcedStyle: not_to` (default)
9
+ #
9
10
  # # bad
10
11
  # it '...' do
11
12
  # expect(false).to_not be_true
@@ -15,6 +16,18 @@ module RuboCop
15
16
  # it '...' do
16
17
  # expect(false).not_to be_true
17
18
  # end
19
+ #
20
+ # @example `EnforcedStyle: to_not`
21
+ #
22
+ # # bad
23
+ # it '...' do
24
+ # expect(false).not_to be_true
25
+ # end
26
+ #
27
+ # # good
28
+ # it '...' do
29
+ # expect(false).to_not be_true
30
+ # end
18
31
  class NotToNot < Base
19
32
  extend AutoCorrector
20
33
  include ConfigurableEnforcedStyle
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ module Rails
7
+ # Checks that tests use `have_http_status` instead of equality matchers.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # expect(response.status).to be(200)
12
+ #
13
+ # # good
14
+ # expect(response).to have_http_status(200)
15
+ #
16
+ class HaveHttpStatus < Base
17
+ extend AutoCorrector
18
+
19
+ MSG =
20
+ 'Prefer `expect(response).%<to>s have_http_status(%<status>i)` ' \
21
+ 'over `expect(response.status).%<to>s %<match>s`.'
22
+
23
+ # @!method match_status(node)
24
+ def_node_matcher :match_status, <<-PATTERN
25
+ (send
26
+ (send nil? :expect
27
+ $(send (send nil? :response) :status)
28
+ )
29
+ $#Runners.all
30
+ $(send nil? {:be :eq :eql :equal} (int $_))
31
+ )
32
+ PATTERN
33
+
34
+ def on_send(node)
35
+ match_status(node) do |response_status, to, match, status|
36
+ message = format(MSG, to: to, match: match.source, status: status)
37
+ add_offense(node, message: message) do |corrector|
38
+ corrector.replace(response_status.source_range, 'response')
39
+ corrector.replace(match.loc.selector, 'have_http_status')
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -11,6 +11,17 @@ module RuboCop
11
11
  #
12
12
  # This cop can be configured using the `EnforcedStyle` option
13
13
  #
14
+ # @example `EnforcedStyle: and_return` (default)
15
+ # # bad
16
+ # allow(Foo).to receive(:bar) { "baz" }
17
+ # expect(Foo).to receive(:bar) { "baz" }
18
+ #
19
+ # # good
20
+ # allow(Foo).to receive(:bar).and_return("baz")
21
+ # expect(Foo).to receive(:bar).and_return("baz")
22
+ # # also good as the returned value is dynamic
23
+ # allow(Foo).to receive(:bar) { bar.baz }
24
+ #
14
25
  # @example `EnforcedStyle: block`
15
26
  # # bad
16
27
  # allow(Foo).to receive(:bar).and_return("baz")
@@ -22,17 +33,6 @@ module RuboCop
22
33
  # # also good as the returned value is dynamic
23
34
  # allow(Foo).to receive(:bar).and_return(bar.baz)
24
35
  #
25
- # @example `EnforcedStyle: and_return`
26
- # # bad
27
- # allow(Foo).to receive(:bar) { "baz" }
28
- # expect(Foo).to receive(:bar) { "baz" }
29
- #
30
- # # good
31
- # allow(Foo).to receive(:bar).and_return("baz")
32
- # expect(Foo).to receive(:bar).and_return("baz")
33
- # # also good as the returned value is dynamic
34
- # allow(Foo).to receive(:bar) { bar.baz }
35
- #
36
36
  class ReturnFromStub < Base
37
37
  extend AutoCorrector
38
38
  include ConfigurableEnforcedStyle
@@ -35,7 +35,7 @@ module RuboCop
35
35
  occurrences.each do |occurrence|
36
36
  lines_except_current = lines - [occurrence.first_line]
37
37
  message = format(MSG, hook_name: occurrences.first.method_name,
38
- lines: lines_msg(lines_except_current))
38
+ lines: lines_msg(lines_except_current))
39
39
  add_offense(occurrence, message: message)
40
40
  end
41
41
  end
@@ -47,7 +47,7 @@ module RuboCop
47
47
  def correct_variable(variable)
48
48
  case variable.type
49
49
  when :dsym
50
- variable.source[1..-1]
50
+ variable.source[1..]
51
51
  when :sym
52
52
  variable.value.to_s.inspect
53
53
  else
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpec
6
- # This cop checks void `expect()`.
6
+ # Checks void `expect()`.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpec
6
- # This cop checks for calling a block within a stub.
6
+ # Checks for calling a block within a stub.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -44,7 +44,7 @@ module RuboCop
44
44
 
45
45
  def autocorrect(corrector, node, range)
46
46
  corrector.replace(
47
- range_with_surrounding_space(range: range, side: :left),
47
+ range_with_surrounding_space(range, side: :left),
48
48
  generate_replacement(node.body)
49
49
  )
50
50
  end
@@ -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/specific_matcher'
5
6
  require_relative 'rspec/capybara/visibility_matcher'
6
7
 
7
8
  require_relative 'rspec/factory_bot/attribute_defined_statically'
@@ -10,6 +11,7 @@ require_relative 'rspec/factory_bot/factory_class_name'
10
11
  require_relative 'rspec/factory_bot/syntax_methods'
11
12
 
12
13
  require_relative 'rspec/rails/avoid_setup_hook'
14
+ require_relative 'rspec/rails/have_http_status'
13
15
  begin
14
16
  require_relative 'rspec/rails/http_status'
15
17
  rescue LoadError
@@ -25,6 +27,7 @@ require_relative 'rspec/be_eq'
25
27
  require_relative 'rspec/be_eql'
26
28
  require_relative 'rspec/be_nil'
27
29
  require_relative 'rspec/before_after_all'
30
+ require_relative 'rspec/change_by_zero'
28
31
  require_relative 'rspec/context_method'
29
32
  require_relative 'rspec/context_wording'
30
33
  require_relative 'rspec/describe_class'
@@ -8,6 +8,7 @@ module RuboCop
8
8
  class ConfigFormatter
9
9
  EXTENSION_ROOT_DEPARTMENT = %r{^(RSpec/)}.freeze
10
10
  SUBDEPARTMENTS = %(RSpec/Capybara RSpec/FactoryBot RSpec/Rails)
11
+ AMENDMENTS = %(Metrics/BlockLength)
11
12
  COP_DOC_BASE_URL = 'https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/'
12
13
 
13
14
  def initialize(config, descriptions)
@@ -18,6 +19,7 @@ module RuboCop
18
19
  def dump
19
20
  YAML.dump(unified_config)
20
21
  .gsub(EXTENSION_ROOT_DEPARTMENT, "\n\\1")
22
+ .gsub(*AMENDMENTS, "\n\\0")
21
23
  .gsub(/^(\s+)- /, '\1 - ')
22
24
  end
23
25
 
@@ -26,6 +28,7 @@ module RuboCop
26
28
  def unified_config
27
29
  cops.each_with_object(config.dup) do |cop, unified|
28
30
  next if SUBDEPARTMENTS.include?(cop)
31
+ next if AMENDMENTS.include?(cop)
29
32
 
30
33
  unified[cop].merge!(descriptions.fetch(cop))
31
34
  unified[cop]['Reference'] = COP_DOC_BASE_URL + cop.sub('RSpec/', '')
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module RSpec
5
5
  # RuboCop RSpec specific extensions of RuboCop::AST::Node
6
6
  module Node
7
- # In various cops we want to regard const as literal althought it's not
7
+ # In various cops we want to regard const as literal although it's not
8
8
  # strictly literal.
9
9
  def recursive_literal_or_const?
10
10
  case type
@@ -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.10.0'
7
+ STRING = '2.12.0'
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.10.0
4
+ version: 2.12.0
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-04-19 00:00:00.000000000 Z
13
+ date: 2022-07-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -18,14 +18,14 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '1.19'
21
+ version: '1.31'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '1.19'
28
+ version: '1.31'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: rack
31
31
  requirement: !ruby/object:Gem::Requirement
@@ -141,7 +141,9 @@ files:
141
141
  - lib/rubocop/cop/rspec/before_after_all.rb
142
142
  - lib/rubocop/cop/rspec/capybara/current_path_expectation.rb
143
143
  - lib/rubocop/cop/rspec/capybara/feature_methods.rb
144
+ - lib/rubocop/cop/rspec/capybara/specific_matcher.rb
144
145
  - lib/rubocop/cop/rspec/capybara/visibility_matcher.rb
146
+ - lib/rubocop/cop/rspec/change_by_zero.rb
145
147
  - lib/rubocop/cop/rspec/context_method.rb
146
148
  - lib/rubocop/cop/rspec/context_wording.rb
147
149
  - lib/rubocop/cop/rspec/describe_class.rb
@@ -206,6 +208,7 @@ files:
206
208
  - lib/rubocop/cop/rspec/pending.rb
207
209
  - lib/rubocop/cop/rspec/predicate_matcher.rb
208
210
  - lib/rubocop/cop/rspec/rails/avoid_setup_hook.rb
211
+ - lib/rubocop/cop/rspec/rails/have_http_status.rb
209
212
  - lib/rubocop/cop/rspec/rails/http_status.rb
210
213
  - lib/rubocop/cop/rspec/receive_counts.rb
211
214
  - lib/rubocop/cop/rspec/receive_never.rb
@@ -262,14 +265,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
262
265
  requirements:
263
266
  - - ">="
264
267
  - !ruby/object:Gem::Version
265
- version: 2.5.0
268
+ version: 2.6.0
266
269
  required_rubygems_version: !ruby/object:Gem::Requirement
267
270
  requirements:
268
271
  - - ">="
269
272
  - !ruby/object:Gem::Version
270
273
  version: '0'
271
274
  requirements: []
272
- rubygems_version: 3.3.1
275
+ rubygems_version: 3.1.6
273
276
  signing_key:
274
277
  specification_version: 4
275
278
  summary: Code style checking for RSpec files