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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/config/default.yml +32 -3
- data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +1 -1
- data/lib/rubocop/cop/rspec/capybara/specific_matcher.rb +77 -0
- data/lib/rubocop/cop/rspec/change_by_zero.rb +93 -0
- data/lib/rubocop/cop/rspec/described_class.rb +13 -20
- data/lib/rubocop/cop/rspec/dialect.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_hook.rb +2 -4
- data/lib/rubocop/cop/rspec/example_length.rb +1 -1
- data/lib/rubocop/cop/rspec/example_without_description.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_actual.rb +2 -0
- data/lib/rubocop/cop/rspec/expect_change.rb +18 -12
- data/lib/rubocop/cop/rspec/expect_output.rb +1 -1
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +32 -9
- data/lib/rubocop/cop/rspec/factory_bot/syntax_methods.rb +1 -1
- data/lib/rubocop/cop/rspec/file_path.rb +2 -1
- data/lib/rubocop/cop/rspec/focus.rb +2 -4
- data/lib/rubocop/cop/rspec/hook_argument.rb +3 -3
- data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -1
- data/lib/rubocop/cop/rspec/it_behaves_like.rb +2 -2
- data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +1 -1
- data/lib/rubocop/cop/rspec/message_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/message_spies.rb +7 -1
- data/lib/rubocop/cop/rspec/mixin/empty_line_separation.rb +13 -4
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +20 -0
- data/lib/rubocop/cop/rspec/not_to_not.rb +14 -1
- data/lib/rubocop/cop/rspec/rails/have_http_status.rb +47 -0
- data/lib/rubocop/cop/rspec/return_from_stub.rb +11 -11
- data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/variable_definition.rb +1 -1
- data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
- data/lib/rubocop/cop/rspec/yield.rb +2 -2
- data/lib/rubocop/cop/rspec_cops.rb +3 -0
- data/lib/rubocop/rspec/config_formatter.rb +3 -0
- data/lib/rubocop/rspec/node.rb +1 -1
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06d6fd83af093abc4da74f5791334c364b86c8238610e53890f4b197f97ce1b6
|
4
|
+
data.tar.gz: 3e40ac4c4e15bee0892061da115755ad8a9cc872218b8cf2d8fe166ea40c6f83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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:
|
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:
|
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:
|
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://
|
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?,
|
82
|
-
|
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) &&
|
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)
|
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?
|
@@ -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
|
-
|
40
|
-
|
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
|
9
|
+
# extracting out some behavior, e.g. with a `let` block, or a helper
|
10
10
|
# method.
|
11
11
|
#
|
12
12
|
# @example
|
@@ -10,14 +10,7 @@ module RuboCop
|
|
10
10
|
#
|
11
11
|
# This cop can be configured using the `EnforcedStyle` option.
|
12
12
|
#
|
13
|
-
# @example `EnforcedStyle:
|
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
|
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
|
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
|
-
# #
|
19
|
-
# 3.times {
|
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
|
37
|
-
def_node_matcher :
|
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
|
-
|
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
|
-
|
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
|
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
|
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/, '')}"
|
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 =
|
73
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
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(
|
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
|
-
|
38
|
+
lines: lines_msg(lines_except_current))
|
39
39
|
add_offense(occurrence, message: message)
|
40
40
|
end
|
41
41
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module RSpec
|
6
|
-
#
|
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
|
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/', '')
|
data/lib/rubocop/rspec/node.rb
CHANGED
@@ -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
|
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
|
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
275
|
+
rubygems_version: 3.1.6
|
273
276
|
signing_key:
|
274
277
|
specification_version: 4
|
275
278
|
summary: Code style checking for RSpec files
|