rubocop-rspec 2.15.0 → 2.17.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 +20 -0
- data/README.md +1 -1
- data/config/default.yml +54 -16
- data/lib/rubocop/cop/rspec/be.rb +2 -0
- data/lib/rubocop/cop/rspec/be_eq.rb +3 -0
- data/lib/rubocop/cop/rspec/be_eql.rb +3 -0
- data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +3 -3
- data/lib/rubocop/cop/rspec/capybara/match_style.rb +60 -0
- data/lib/rubocop/cop/rspec/capybara/negation_matcher.rb +1 -1
- data/lib/rubocop/cop/rspec/capybara/specific_actions.rb +1 -1
- data/lib/rubocop/cop/rspec/capybara/specific_finders.rb +1 -1
- data/lib/rubocop/cop/rspec/capybara/specific_matcher.rb +3 -5
- data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +1 -1
- data/lib/rubocop/cop/rspec/context_wording.rb +0 -1
- data/lib/rubocop/cop/rspec/duplicated_metadata.rb +58 -0
- data/lib/rubocop/cop/rspec/empty_line_after_example.rb +2 -0
- data/lib/rubocop/cop/rspec/expect_actual.rb +2 -0
- data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +1 -1
- data/lib/rubocop/cop/rspec/factory_bot/consistent_parentheses_style.rb +5 -3
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +9 -2
- data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +1 -1
- data/lib/rubocop/cop/rspec/factory_bot/factory_name_style.rb +74 -0
- data/lib/rubocop/cop/rspec/implicit_expect.rb +2 -0
- data/lib/rubocop/cop/rspec/leading_subject.rb +2 -2
- data/lib/rubocop/cop/rspec/message_spies.rb +2 -0
- data/lib/rubocop/cop/rspec/mixin/metadata.rb +49 -0
- data/lib/rubocop/cop/rspec/pending_without_reason.rb +121 -0
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +4 -1
- data/lib/rubocop/cop/rspec/rails/have_http_status.rb +5 -2
- data/lib/rubocop/cop/rspec/rails/inferred_spec_type.rb +1 -1
- data/lib/rubocop/cop/rspec/rails/minitest_assertions.rb +60 -0
- data/lib/rubocop/cop/rspec/scattered_setup.rb +2 -0
- data/lib/rubocop/cop/rspec/sort_metadata.rb +4 -35
- data/lib/rubocop/cop/rspec/stubbed_mock.rb +3 -1
- data/lib/rubocop/cop/rspec/subject_stub.rb +0 -1
- data/lib/rubocop/cop/rspec/unspecified_exception.rb +2 -0
- data/lib/rubocop/cop/rspec_cops.rb +5 -0
- data/lib/rubocop/rspec/config_formatter.rb +2 -2
- data/lib/rubocop/rspec/description_extractor.rb +5 -10
- data/lib/rubocop/rspec/language.rb +6 -2
- data/lib/rubocop/rspec/version.rb +1 -1
- data/lib/rubocop-rspec.rb +18 -13
- metadata +9 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 803b0cb494f6f1204fdb3ec31f7d4a4113b57fb2384066fb322e84107abbc65a
|
|
4
|
+
data.tar.gz: cb5a6a141c0af43cf179ac9d3e568e8bc3b5764abf4fda4e8a09340e7d311161
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 263c0f3e23a10ba54a9fc888646ab9f4e55ea4a08e0adb5b2b32db14c1fc773ed3fa956df3c7a12794c7c3ebea4415e68a42a5d7d109e2da6b88d623417e2102
|
|
7
|
+
data.tar.gz: d976c48d81cfd2d33b4857f08c9860d3857d5f8b51017f99c5ae650102184884dc76d95096d1efc2b70472a063a1887ef4d8e72dc7a6d003b131bf4ca67c4c5e
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
## Master (Unreleased)
|
|
4
4
|
|
|
5
|
+
## 2.17.0 (2023-01-13)
|
|
6
|
+
|
|
7
|
+
- Fix a false positive for `RSpec/PendingWithoutReason` when pending/skip is argument of methods. ([@ydah])
|
|
8
|
+
- Add new `RSpec/Capybara/MatchStyle` cop. ([@ydah])
|
|
9
|
+
- Add new `RSpec/Rails/MinitestAssertions` cop. ([@ydah])
|
|
10
|
+
- Fix a false positive for `RSpec/PendingWithoutReason` when not inside example. ([@ydah])
|
|
11
|
+
- Fix a false negative for `RSpec/PredicateMatcher` when using `include` and `respond_to`. ([@ydah])
|
|
12
|
+
- Fix a false positive for `RSpec/StubbedMock` when stubbed message expectation with a block and block parameter. ([@ydah])
|
|
13
|
+
|
|
14
|
+
## 2.16.0 (2022-12-13)
|
|
15
|
+
|
|
16
|
+
- Add new `RSpec/FactoryBot/FactoryNameStyle` cop. ([@ydah])
|
|
17
|
+
- Improved processing speed for `RSpec/Be`, `RSpec/ExpectActual`, `RSpec/ImplicitExpect`, `RSpec/MessageSpies`, `RSpec/PredicateMatcher` and `RSpec/Rails/HaveHttpStatus`. ([@ydah])
|
|
18
|
+
- Fix wrong autocorrection in `n_times` style on `RSpec/FactoryBot/CreateList`. ([@r7kamura])
|
|
19
|
+
- Fix a false positive for `RSpec/FactoryBot/ConsistentParenthesesStyle` when using `generate` with multiple arguments. ([@ydah])
|
|
20
|
+
- Mark `RSpec/BeEq` as `Safe: false` ([@r7kamura])
|
|
21
|
+
- Add `RSpec/DuplicatedMetadata` cop. ([@r7kamura])
|
|
22
|
+
- Mark `RSpec/BeEql` as `Safe: false`. ([@r7kamura])
|
|
23
|
+
- Add `RSpec/PendingWithoutReason` cop. ([@r7kamura])
|
|
24
|
+
|
|
5
25
|
## 2.15.0 (2022-11-03)
|
|
6
26
|
|
|
7
27
|
- Fix a false positive for `RSpec/RepeatedDescription` when different its block expectations are used. ([@ydah])
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://gitter.im/rubocop-rspec/Lobby)
|
|
4
4
|
[](https://rubygems.org/gems/rubocop-rspec)
|
|
5
|
-

|
|
6
6
|
|
|
7
7
|
RSpec-specific analysis for your projects, as an extension to
|
|
8
8
|
[RuboCop](https://github.com/rubocop/rubocop).
|
data/config/default.yml
CHANGED
|
@@ -147,13 +147,17 @@ RSpec/Be:
|
|
|
147
147
|
RSpec/BeEq:
|
|
148
148
|
Description: Check for expectations where `be(...)` can replace `eq(...)`.
|
|
149
149
|
Enabled: pending
|
|
150
|
+
Safe: false
|
|
150
151
|
VersionAdded: 2.9.0
|
|
152
|
+
VersionChanged: '2.16'
|
|
151
153
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeEq
|
|
152
154
|
|
|
153
155
|
RSpec/BeEql:
|
|
154
156
|
Description: Check for expectations where `be(...)` can replace `eql(...)`.
|
|
155
157
|
Enabled: true
|
|
158
|
+
Safe: false
|
|
156
159
|
VersionAdded: '1.7'
|
|
160
|
+
VersionChanged: '2.16'
|
|
157
161
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeEql
|
|
158
162
|
|
|
159
163
|
RSpec/BeNil:
|
|
@@ -284,6 +288,12 @@ RSpec/Dialect:
|
|
|
284
288
|
VersionAdded: '1.33'
|
|
285
289
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Dialect
|
|
286
290
|
|
|
291
|
+
RSpec/DuplicatedMetadata:
|
|
292
|
+
Description: Avoid duplicated metadata.
|
|
293
|
+
Enabled: pending
|
|
294
|
+
VersionAdded: '2.16'
|
|
295
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DuplicatedMetadata
|
|
296
|
+
|
|
287
297
|
RSpec/EmptyExampleGroup:
|
|
288
298
|
Description: Checks if an example group does not include any tests.
|
|
289
299
|
Enabled: true
|
|
@@ -356,12 +366,6 @@ RSpec/ExampleWithoutDescription:
|
|
|
356
366
|
VersionAdded: '1.22'
|
|
357
367
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleWithoutDescription
|
|
358
368
|
|
|
359
|
-
RSpec/ExcessiveDocstringSpacing:
|
|
360
|
-
Description: Checks for excessive whitespace in example descriptions.
|
|
361
|
-
Enabled: pending
|
|
362
|
-
VersionAdded: '2.5'
|
|
363
|
-
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExcessiveDocstringSpacing
|
|
364
|
-
|
|
365
369
|
RSpec/ExampleWording:
|
|
366
370
|
Description: Checks for common mistakes in example descriptions.
|
|
367
371
|
Enabled: true
|
|
@@ -378,6 +382,12 @@ RSpec/ExampleWording:
|
|
|
378
382
|
StyleGuide: https://rspec.rubystyle.guide/#should-in-example-docstrings
|
|
379
383
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleWording
|
|
380
384
|
|
|
385
|
+
RSpec/ExcessiveDocstringSpacing:
|
|
386
|
+
Description: Checks for excessive whitespace in example descriptions.
|
|
387
|
+
Enabled: pending
|
|
388
|
+
VersionAdded: '2.5'
|
|
389
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExcessiveDocstringSpacing
|
|
390
|
+
|
|
381
391
|
RSpec/ExpectActual:
|
|
382
392
|
Description: Checks for `expect(...)` calls containing literal values.
|
|
383
393
|
Enabled: true
|
|
@@ -664,6 +674,12 @@ RSpec/Pending:
|
|
|
664
674
|
VersionAdded: '1.25'
|
|
665
675
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Pending
|
|
666
676
|
|
|
677
|
+
RSpec/PendingWithoutReason:
|
|
678
|
+
Description: Checks for pending or skipped examples without reason.
|
|
679
|
+
Enabled: pending
|
|
680
|
+
VersionAdded: '2.16'
|
|
681
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/PendingWithoutReason
|
|
682
|
+
|
|
667
683
|
RSpec/PredicateMatcher:
|
|
668
684
|
Description: Prefer using predicate matcher over using predicate method directly.
|
|
669
685
|
Enabled: true
|
|
@@ -871,6 +887,12 @@ RSpec/Capybara/FeatureMethods:
|
|
|
871
887
|
VersionChanged: '2.0'
|
|
872
888
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods
|
|
873
889
|
|
|
890
|
+
RSpec/Capybara/MatchStyle:
|
|
891
|
+
Description: Checks for usage of deprecated style methods.
|
|
892
|
+
Enabled: pending
|
|
893
|
+
VersionAdded: '2.17'
|
|
894
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/MatchStyle
|
|
895
|
+
|
|
874
896
|
RSpec/Capybara/NegationMatcher:
|
|
875
897
|
Description: Enforces use of `have_no_*` or `not_to` for negated expectations.
|
|
876
898
|
Enabled: pending
|
|
@@ -960,6 +982,16 @@ RSpec/FactoryBot/FactoryClassName:
|
|
|
960
982
|
VersionChanged: '2.0'
|
|
961
983
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/FactoryClassName
|
|
962
984
|
|
|
985
|
+
RSpec/FactoryBot/FactoryNameStyle:
|
|
986
|
+
Description: Checks for name style for argument of FactoryBot::Syntax::Methods.
|
|
987
|
+
Enabled: pending
|
|
988
|
+
VersionAdded: '2.16'
|
|
989
|
+
EnforcedStyle: symbol
|
|
990
|
+
SupportedStyles:
|
|
991
|
+
- symbol
|
|
992
|
+
- string
|
|
993
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/FactoryNameStyle
|
|
994
|
+
|
|
963
995
|
RSpec/FactoryBot/SyntaxMethods:
|
|
964
996
|
Description: Use shorthands from `FactoryBot::Syntax::Methods` in your specs.
|
|
965
997
|
Enabled: pending
|
|
@@ -985,6 +1017,17 @@ RSpec/Rails/HaveHttpStatus:
|
|
|
985
1017
|
VersionAdded: '2.12'
|
|
986
1018
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HaveHttpStatus
|
|
987
1019
|
|
|
1020
|
+
RSpec/Rails/HttpStatus:
|
|
1021
|
+
Description: Enforces use of symbolic or numeric value to describe HTTP status.
|
|
1022
|
+
Enabled: true
|
|
1023
|
+
EnforcedStyle: symbolic
|
|
1024
|
+
SupportedStyles:
|
|
1025
|
+
- numeric
|
|
1026
|
+
- symbolic
|
|
1027
|
+
VersionAdded: '1.23'
|
|
1028
|
+
VersionChanged: '2.0'
|
|
1029
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HttpStatus
|
|
1030
|
+
|
|
988
1031
|
RSpec/Rails/InferredSpecType:
|
|
989
1032
|
Description: Identifies redundant spec type.
|
|
990
1033
|
Enabled: pending
|
|
@@ -1008,13 +1051,8 @@ RSpec/Rails/InferredSpecType:
|
|
|
1008
1051
|
system: system
|
|
1009
1052
|
views: view
|
|
1010
1053
|
|
|
1011
|
-
RSpec/Rails/
|
|
1012
|
-
Description:
|
|
1013
|
-
Enabled:
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
- numeric
|
|
1017
|
-
- symbolic
|
|
1018
|
-
VersionAdded: '1.23'
|
|
1019
|
-
VersionChanged: '2.0'
|
|
1020
|
-
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HttpStatus
|
|
1054
|
+
RSpec/Rails/MinitestAssertions:
|
|
1055
|
+
Description: Check if using Minitest matchers.
|
|
1056
|
+
Enabled: pending
|
|
1057
|
+
VersionAdded: '2.17'
|
|
1058
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/MinitestAssertions
|
data/lib/rubocop/cop/rspec/be.rb
CHANGED
|
@@ -9,6 +9,9 @@ module RuboCop
|
|
|
9
9
|
# using `==`. Booleans and nil can be compared by identity and therefore
|
|
10
10
|
# the `be` matcher is preferable as it is a more strict test.
|
|
11
11
|
#
|
|
12
|
+
# @safety
|
|
13
|
+
# This cop is unsafe because it changes how values are compared.
|
|
14
|
+
#
|
|
12
15
|
# @example
|
|
13
16
|
# # bad
|
|
14
17
|
# expect(foo).to eq(true)
|
|
@@ -10,6 +10,9 @@ module RuboCop
|
|
|
10
10
|
# can be compared by identity and therefore the `be` matcher is
|
|
11
11
|
# preferable as it is a more strict test.
|
|
12
12
|
#
|
|
13
|
+
# @safety
|
|
14
|
+
# This cop is unsafe because it changes how values are compared.
|
|
15
|
+
#
|
|
13
16
|
# @example
|
|
14
17
|
# # bad
|
|
15
18
|
# expect(foo).to eql(1)
|
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
|
29
29
|
# # good
|
|
30
30
|
# expect(page).to have_current_path('/callback')
|
|
31
31
|
#
|
|
32
|
-
class CurrentPathExpectation < Base
|
|
32
|
+
class CurrentPathExpectation < ::RuboCop::Cop::Base
|
|
33
33
|
extend AutoCorrector
|
|
34
34
|
|
|
35
35
|
MSG = 'Do not set an RSpec expectation on `current_path` in ' \
|
|
@@ -47,14 +47,14 @@ module RuboCop
|
|
|
47
47
|
# @!method as_is_matcher(node)
|
|
48
48
|
def_node_matcher :as_is_matcher, <<-PATTERN
|
|
49
49
|
(send
|
|
50
|
-
#expectation_set_on_current_path
|
|
50
|
+
#expectation_set_on_current_path ${:to :to_not :not_to}
|
|
51
51
|
${(send nil? :eq ...) (send nil? :match (regexp ...))})
|
|
52
52
|
PATTERN
|
|
53
53
|
|
|
54
54
|
# @!method regexp_str_matcher(node)
|
|
55
55
|
def_node_matcher :regexp_str_matcher, <<-PATTERN
|
|
56
56
|
(send
|
|
57
|
-
#expectation_set_on_current_path
|
|
57
|
+
#expectation_set_on_current_path ${:to :to_not :not_to}
|
|
58
58
|
$(send nil? :match (str $_)))
|
|
59
59
|
PATTERN
|
|
60
60
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RSpec
|
|
6
|
+
module Capybara
|
|
7
|
+
# Checks for usage of deprecated style methods.
|
|
8
|
+
#
|
|
9
|
+
# @example when using `assert_style`
|
|
10
|
+
# # bad
|
|
11
|
+
# page.find(:css, '#first').assert_style(display: 'block')
|
|
12
|
+
#
|
|
13
|
+
# # good
|
|
14
|
+
# page.find(:css, '#first').assert_matches_style(display: 'block')
|
|
15
|
+
#
|
|
16
|
+
# @example when using `has_style?`
|
|
17
|
+
# # bad
|
|
18
|
+
# expect(page.find(:css, 'first')
|
|
19
|
+
# .has_style?(display: 'block')).to be true
|
|
20
|
+
#
|
|
21
|
+
# # good
|
|
22
|
+
# expect(page.find(:css, 'first')
|
|
23
|
+
# .matches_style?(display: 'block')).to be true
|
|
24
|
+
#
|
|
25
|
+
# @example when using `have_style`
|
|
26
|
+
# # bad
|
|
27
|
+
# expect(page).to have_style(display: 'block')
|
|
28
|
+
#
|
|
29
|
+
# # good
|
|
30
|
+
# expect(page).to match_style(display: 'block')
|
|
31
|
+
#
|
|
32
|
+
class MatchStyle < Base
|
|
33
|
+
extend AutoCorrector
|
|
34
|
+
|
|
35
|
+
MSG = 'Use `%<good>s` instead of `%<bad>s`.'
|
|
36
|
+
RESTRICT_ON_SEND = %i[assert_style has_style? have_style].freeze
|
|
37
|
+
PREFERRED_METHOD = {
|
|
38
|
+
'assert_style' => 'assert_matches_style',
|
|
39
|
+
'has_style?' => 'matches_style?',
|
|
40
|
+
'have_style' => 'match_style'
|
|
41
|
+
}.freeze
|
|
42
|
+
|
|
43
|
+
def on_send(node)
|
|
44
|
+
method_node = node.loc.selector
|
|
45
|
+
add_offense(method_node) do |corrector|
|
|
46
|
+
corrector.replace(method_node,
|
|
47
|
+
PREFERRED_METHOD[method_node.source])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def message(node)
|
|
54
|
+
format(MSG, good: PREFERRED_METHOD[node.source], bad: node.source)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
|
20
20
|
# click_link(exact_text: 'foo')
|
|
21
21
|
# find('div').click_button
|
|
22
22
|
#
|
|
23
|
-
class SpecificActions < Base
|
|
23
|
+
class SpecificActions < ::RuboCop::Cop::Base
|
|
24
24
|
MSG = "Prefer `%<good_action>s` over `find('%<selector>s').click`."
|
|
25
25
|
RESTRICT_ON_SEND = %i[click].freeze
|
|
26
26
|
SPECIFIC_ACTION = {
|
|
@@ -26,9 +26,7 @@ module RuboCop
|
|
|
26
26
|
# expect(page).to have_select
|
|
27
27
|
# expect(page).to have_field('foo')
|
|
28
28
|
#
|
|
29
|
-
class SpecificMatcher < Base
|
|
30
|
-
include CapybaraHelp
|
|
31
|
-
|
|
29
|
+
class SpecificMatcher < ::RuboCop::Cop::Base
|
|
32
30
|
MSG = 'Prefer `%<good_matcher>s` over `%<bad_matcher>s`.'
|
|
33
31
|
RESTRICT_ON_SEND = %i[have_selector have_no_selector have_css
|
|
34
32
|
have_no_css].freeze
|
|
@@ -49,8 +47,8 @@ module RuboCop
|
|
|
49
47
|
first_argument(node) do |arg|
|
|
50
48
|
next unless (matcher = specific_matcher(arg))
|
|
51
49
|
next if CssSelector.multiple_selectors?(arg)
|
|
52
|
-
next unless specific_option?(node, arg, matcher)
|
|
53
|
-
next unless specific_pseudo_classes?(arg)
|
|
50
|
+
next unless CapybaraHelp.specific_option?(node, arg, matcher)
|
|
51
|
+
next unless CapybaraHelp.specific_pseudo_classes?(arg)
|
|
54
52
|
|
|
55
53
|
add_offense(node, message: message(node, matcher))
|
|
56
54
|
end
|
|
@@ -26,7 +26,7 @@ module RuboCop
|
|
|
26
26
|
# expect(page).to have_css('.foo', visible: :all)
|
|
27
27
|
# expect(page).to have_link('my link', visible: :hidden)
|
|
28
28
|
#
|
|
29
|
-
class VisibilityMatcher < Base
|
|
29
|
+
class VisibilityMatcher < ::RuboCop::Cop::Base
|
|
30
30
|
MSG_FALSE = 'Use `:all` or `:hidden` instead of `false`.'
|
|
31
31
|
MSG_TRUE = 'Use `:visible` instead of `true`.'
|
|
32
32
|
CAPYBARA_MATCHER_METHODS = %w[
|
|
@@ -10,7 +10,6 @@ module RuboCop
|
|
|
10
10
|
# include `if`, `unless`, `for`, `before`, `after`, or `during`.
|
|
11
11
|
# They may consist of multiple words if desired.
|
|
12
12
|
#
|
|
13
|
-
# @see https://rspec.rubystyle.guide/#context-descriptions
|
|
14
13
|
# @see http://www.betterspecs.org/#contexts
|
|
15
14
|
#
|
|
16
15
|
# @example `Prefixes` configuration
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RSpec
|
|
6
|
+
# Avoid duplicated metadata.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# # bad
|
|
10
|
+
# describe 'Something', :a, :a
|
|
11
|
+
#
|
|
12
|
+
# # good
|
|
13
|
+
# describe 'Something', :a
|
|
14
|
+
class DuplicatedMetadata < Base
|
|
15
|
+
extend AutoCorrector
|
|
16
|
+
|
|
17
|
+
include Metadata
|
|
18
|
+
include RangeHelp
|
|
19
|
+
|
|
20
|
+
MSG = 'Avoid duplicated metadata.'
|
|
21
|
+
|
|
22
|
+
def on_metadata(symbols, _pairs)
|
|
23
|
+
symbols.each do |symbol|
|
|
24
|
+
on_metadata_symbol(symbol)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def on_metadata_symbol(node)
|
|
31
|
+
return unless duplicated?(node)
|
|
32
|
+
|
|
33
|
+
add_offense(node) do |corrector|
|
|
34
|
+
autocorrect(corrector, node)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def autocorrect(corrector, node)
|
|
39
|
+
corrector.remove(
|
|
40
|
+
range_with_surrounding_comma(
|
|
41
|
+
range_with_surrounding_space(
|
|
42
|
+
node.location.expression,
|
|
43
|
+
side: :left
|
|
44
|
+
),
|
|
45
|
+
:left
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def duplicated?(node)
|
|
51
|
+
node.left_siblings.any? do |sibling|
|
|
52
|
+
sibling.eql?(node)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
|
40
40
|
# name: 'foo'
|
|
41
41
|
# )
|
|
42
42
|
#
|
|
43
|
-
class ConsistentParenthesesStyle < Base
|
|
43
|
+
class ConsistentParenthesesStyle < ::RuboCop::Cop::Base
|
|
44
44
|
extend AutoCorrector
|
|
45
45
|
include ConfigurableEnforcedStyle
|
|
46
46
|
include RuboCop::RSpec::FactoryBot::Language
|
|
@@ -69,6 +69,8 @@ module RuboCop
|
|
|
69
69
|
return if ambiguous_without_parentheses?(node)
|
|
70
70
|
|
|
71
71
|
factory_call(node) do
|
|
72
|
+
return if node.method?(:generate) && node.arguments.count > 1
|
|
73
|
+
|
|
72
74
|
if node.parenthesized?
|
|
73
75
|
process_with_parentheses(node)
|
|
74
76
|
else
|
|
@@ -77,6 +79,8 @@ module RuboCop
|
|
|
77
79
|
end
|
|
78
80
|
end
|
|
79
81
|
|
|
82
|
+
private
|
|
83
|
+
|
|
80
84
|
def process_with_parentheses(node)
|
|
81
85
|
return unless style == :omit_parentheses
|
|
82
86
|
return unless same_line?(node, node.first_argument)
|
|
@@ -102,8 +106,6 @@ module RuboCop
|
|
|
102
106
|
node.parent&.array_type?
|
|
103
107
|
end
|
|
104
108
|
|
|
105
|
-
private
|
|
106
|
-
|
|
107
109
|
def remove_parentheses(corrector, node)
|
|
108
110
|
corrector.replace(node.location.begin, ' ')
|
|
109
111
|
corrector.remove(node.location.end)
|
|
@@ -31,7 +31,7 @@ module RuboCop
|
|
|
31
31
|
# # good
|
|
32
32
|
# 3.times { create :user }
|
|
33
33
|
#
|
|
34
|
-
class CreateList < Base
|
|
34
|
+
class CreateList < ::RuboCop::Cop::Base
|
|
35
35
|
extend AutoCorrector
|
|
36
36
|
include ConfigurableEnforcedStyle
|
|
37
37
|
include RuboCop::RSpec::FactoryBot::Language
|
|
@@ -143,7 +143,7 @@ module RuboCop
|
|
|
143
143
|
|
|
144
144
|
def call(corrector)
|
|
145
145
|
replacement = generate_n_times_block(node)
|
|
146
|
-
corrector.replace(node, replacement)
|
|
146
|
+
corrector.replace(node.block_node || node, replacement)
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
private
|
|
@@ -159,8 +159,15 @@ module RuboCop
|
|
|
159
159
|
|
|
160
160
|
replacement = format_receiver(node.receiver)
|
|
161
161
|
replacement += format_method_call(node, 'create', arguments)
|
|
162
|
+
replacement += " #{factory_call_block_source}" if node.block_node
|
|
162
163
|
"#{count.source}.times { #{replacement} }"
|
|
163
164
|
end
|
|
165
|
+
|
|
166
|
+
def factory_call_block_source
|
|
167
|
+
node.block_node.location.begin.with(
|
|
168
|
+
end_pos: node.block_node.location.end.end_pos
|
|
169
|
+
).source
|
|
170
|
+
end
|
|
164
171
|
end
|
|
165
172
|
|
|
166
173
|
# :nodoc:
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RSpec
|
|
6
|
+
module FactoryBot
|
|
7
|
+
# Checks for name style for argument of FactoryBot::Syntax::Methods.
|
|
8
|
+
#
|
|
9
|
+
# @example EnforcedStyle: symbol (default)
|
|
10
|
+
# # bad
|
|
11
|
+
# create('user')
|
|
12
|
+
# build "user", username: "NAME"
|
|
13
|
+
#
|
|
14
|
+
# # good
|
|
15
|
+
# create(:user)
|
|
16
|
+
# build :user, username: "NAME"
|
|
17
|
+
#
|
|
18
|
+
# @example EnforcedStyle: string
|
|
19
|
+
# # bad
|
|
20
|
+
# create(:user)
|
|
21
|
+
# build :user, username: "NAME"
|
|
22
|
+
#
|
|
23
|
+
# # good
|
|
24
|
+
# create('user')
|
|
25
|
+
# build "user", username: "NAME"
|
|
26
|
+
#
|
|
27
|
+
class FactoryNameStyle < ::RuboCop::Cop::Base
|
|
28
|
+
extend AutoCorrector
|
|
29
|
+
include ConfigurableEnforcedStyle
|
|
30
|
+
include RuboCop::RSpec::FactoryBot::Language
|
|
31
|
+
|
|
32
|
+
MSG = 'Use %<prefer>s to refer to a factory.'
|
|
33
|
+
FACTORY_CALLS = RuboCop::RSpec::FactoryBot::Language::METHODS
|
|
34
|
+
RESTRICT_ON_SEND = FACTORY_CALLS
|
|
35
|
+
|
|
36
|
+
# @!method factory_call(node)
|
|
37
|
+
def_node_matcher :factory_call, <<-PATTERN
|
|
38
|
+
(send
|
|
39
|
+
{#factory_bot? nil?} %FACTORY_CALLS
|
|
40
|
+
${str sym} ...
|
|
41
|
+
)
|
|
42
|
+
PATTERN
|
|
43
|
+
|
|
44
|
+
def on_send(node)
|
|
45
|
+
factory_call(node) do |name|
|
|
46
|
+
if offense_for_symbol_style?(name)
|
|
47
|
+
register_offense(name, name.value.to_sym.inspect)
|
|
48
|
+
elsif offense_for_string_style?(name)
|
|
49
|
+
register_offense(name, name.value.to_s.inspect)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def offense_for_symbol_style?(name)
|
|
57
|
+
name.str_type? && style == :symbol
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def offense_for_string_style?(name)
|
|
61
|
+
name.sym_type? && style == :string
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def register_offense(name, prefer)
|
|
65
|
+
add_offense(name,
|
|
66
|
+
message: format(MSG, prefer: style.to_s)) do |corrector|
|
|
67
|
+
corrector.replace(name, prefer)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -44,6 +44,8 @@ module RuboCop
|
|
|
44
44
|
check_previous_nodes(node)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
private
|
|
48
|
+
|
|
47
49
|
def check_previous_nodes(node)
|
|
48
50
|
offending_node(node) do |offender|
|
|
49
51
|
msg = format(MSG, offending: offender.method_name)
|
|
@@ -53,8 +55,6 @@ module RuboCop
|
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
57
|
|
|
56
|
-
private
|
|
57
|
-
|
|
58
58
|
def offending_node(node)
|
|
59
59
|
parent(node).each_child_node.find do |sibling|
|
|
60
60
|
break if sibling.equal?(node)
|