rubocop-rspec 2.21.0 → 2.23.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 +21 -0
- data/README.md +1 -1
- data/config/default.yml +37 -16
- data/config/obsoletion.yml +6 -0
- data/lib/rubocop/cop/rspec/empty_example_group.rb +3 -0
- data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +11 -4
- data/lib/rubocop/cop/rspec/expect_actual.rb +2 -2
- data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +25 -118
- data/lib/rubocop/cop/rspec/factory_bot/consistent_parentheses_style.rb +40 -107
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +30 -250
- data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +19 -46
- data/lib/rubocop/cop/rspec/factory_bot/factory_name_style.rb +23 -64
- data/lib/rubocop/cop/rspec/factory_bot/syntax_methods.rb +45 -79
- data/lib/rubocop/cop/rspec/focus.rb +13 -0
- data/lib/rubocop/cop/rspec/indexed_let.rb +32 -1
- data/lib/rubocop/cop/rspec/instance_variable.rb +1 -1
- data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +1 -1
- data/lib/rubocop/cop/rspec/let_before_examples.rb +4 -0
- data/lib/rubocop/cop/rspec/named_subject.rb +1 -1
- data/lib/rubocop/cop/rspec/pending.rb +12 -2
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +3 -3
- data/lib/rubocop/cop/rspec/rails/negation_be_valid.rb +92 -0
- data/lib/rubocop/cop/rspec/receive_messages.rb +155 -0
- data/lib/rubocop/cop/rspec/verified_double_reference.rb +1 -1
- data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -1
- data/lib/rubocop/cop/rspec_cops.rb +2 -0
- data/lib/rubocop/rspec/config_formatter.rb +6 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- data/lib/rubocop-rspec.rb +1 -3
- metadata +18 -4
- data/lib/rubocop/rspec/factory_bot/language.rb +0 -37
- data/lib/rubocop/rspec/factory_bot.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0eebbfb772c1598b0ee4cfe88c74d8b81171e197dbd4d5dc6020df95005440e
|
4
|
+
data.tar.gz: 2936be502e0062b94a0346bd98696194fd33fe6f7693f8c92bc38a952ee31b26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14e3e53093b7e104ab212217fdc8226a909fba9bdd84fa44c22963cf8e62d17ce858a2180b8b5b3727b5dd2a74a9b4c6e2139d8d61cbc6595b2c46f9022214af
|
7
|
+
data.tar.gz: 9408c50d35ae50e1825fef43f2c6a6def0d87e44bfbbd968bb19996b1a867f215df36ab62d451af892e6855c4330c0d4fb9d09b8400ff5f35b4ecef1cfb86adb
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,24 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 2.23.0 (2023-07-30)
|
6
|
+
|
7
|
+
- Add new `RSpec/Rails/NegationBeValid` cop. ([@ydah])
|
8
|
+
- Fix a false negative for `RSpec/ExcessiveDocstringSpacing` when finds description with em space. ([@ydah])
|
9
|
+
- Fix a false positive for `RSpec/EmptyExampleGroup` when example group with examples defined in `if` branch inside iterator. ([@ydah])
|
10
|
+
- Update the message output of `RSpec/ExpectActual` to include the word 'value'. ([@corydiamand])
|
11
|
+
- Fix a false negative for `RSpec/Pending` when `it` without body. ([@ydah])
|
12
|
+
- Add new `RSpec/ReceiveMessages` cop. ([@ydah])
|
13
|
+
- Change default.yml path to use `**/spec/*` instead of `spec/*`. ([@ydah])
|
14
|
+
- Add `AllowedIdentifiers` and `AllowedPatterns` configuration option to `RSpec/IndexedLet`. ([@ydah])
|
15
|
+
- Fix `RSpec/NamedSubject` when block has no body. ([@splattael])
|
16
|
+
- Fix `RSpec/LetBeforeExamples` autocorrect incompatible with `RSpec/ScatteredLet` autocorrect. ([@ydah])
|
17
|
+
- Update `RSpec/Focus` to support `shared_context` and `shared_examples` ([@tmaier])
|
18
|
+
|
19
|
+
## 2.22.0 (2023-05-06)
|
20
|
+
|
21
|
+
- Extract factory_bot cops to a separate repository, [`rubocop-factory_bot`](https://github.com/rubocop/rubocop-factory_bot). The `rubocop-factory_bot` repository is a dependency of `rubocop-rspec` and the factory_bot cops are aliased (`RSpec/FactoryBot/Foo` == `FactoryBot/Foo`) until v3.0 is released, so the change will be invisible to users until then. ([@ydah])
|
22
|
+
|
5
23
|
## 2.21.0 (2023-05-05)
|
6
24
|
|
7
25
|
- Fix a false positive in `RSpec/IndexedLet` with suffixes after index-like numbers. ([@pirj])
|
@@ -777,6 +795,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
777
795
|
[@cfabianski]: https://github.com/cfabianski
|
778
796
|
[@clupprich]: https://github.com/clupprich
|
779
797
|
[@composerinteralia]: https://github.com/composerinteralia
|
798
|
+
[@corydiamand]: https://github.com/corydiamand
|
780
799
|
[@darhazer]: https://github.com/Darhazer
|
781
800
|
[@daveworth]: https://github.com/daveworth
|
782
801
|
[@dduugg]: https://github.com/dduugg
|
@@ -855,6 +874,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
855
874
|
[@seanpdoyle]: https://github.com/seanpdoyle
|
856
875
|
[@sl4vr]: https://github.com/sl4vr
|
857
876
|
[@smcgivern]: https://github.com/smcgivern
|
877
|
+
[@splattael]: https://github.com/splattael
|
858
878
|
[@stephannv]: https://github.com/stephannv
|
859
879
|
[@t3h2mas]: https://github.com/t3h2mas
|
860
880
|
[@tdeo]: https://github.com/tdeo
|
@@ -862,6 +882,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
862
882
|
[@telmofcosta]: https://github.com/telmofcosta
|
863
883
|
[@tietew]: https://github.com/Tietew
|
864
884
|
[@timrogers]: https://github.com/timrogers
|
885
|
+
[@tmaier]: https://github.com/tmaier
|
865
886
|
[@topalovic]: https://github.com/topalovic
|
866
887
|
[@twalpole]: https://github.com/twalpole
|
867
888
|
[@vzvu3k6k]: https://github.com/vzvu3k6k
|
data/README.md
CHANGED
data/config/default.yml
CHANGED
@@ -181,10 +181,11 @@ RSpec/BeforeAfterAll:
|
|
181
181
|
Description: Check that before/after(:all) isn't being used.
|
182
182
|
Enabled: true
|
183
183
|
Exclude:
|
184
|
-
- spec/spec_helper.rb
|
185
|
-
- spec/rails_helper.rb
|
186
|
-
- spec/support/**/*.rb
|
184
|
+
- "**/spec/spec_helper.rb"
|
185
|
+
- "**/spec/rails_helper.rb"
|
186
|
+
- "**/spec/support/**/*.rb"
|
187
187
|
VersionAdded: '1.12'
|
188
|
+
VersionChanged: '2.23'
|
188
189
|
StyleGuide: https://rspec.rubystyle.guide/#avoid-hooks-with-context-scope
|
189
190
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeforeAfterAll
|
190
191
|
|
@@ -404,8 +405,9 @@ RSpec/ExpectActual:
|
|
404
405
|
Description: Checks for `expect(...)` calls containing literal values.
|
405
406
|
Enabled: true
|
406
407
|
Exclude:
|
407
|
-
- spec/routing/**/*
|
408
|
+
- "**/spec/routing/**/*"
|
408
409
|
VersionAdded: '1.7'
|
410
|
+
VersionChanged: '2.23'
|
409
411
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectActual
|
410
412
|
|
411
413
|
RSpec/ExpectChange:
|
@@ -513,8 +515,11 @@ RSpec/IndexedLet:
|
|
513
515
|
Description: Do not set up test data using indexes (e.g., `item_1`, `item_2`).
|
514
516
|
Enabled: pending
|
515
517
|
VersionAdded: '2.20'
|
518
|
+
VersionChanged: '2.23'
|
516
519
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/IndexedLet
|
517
520
|
Max: 1
|
521
|
+
AllowedIdentifiers: []
|
522
|
+
AllowedPatterns: []
|
518
523
|
|
519
524
|
RSpec/InstanceSpy:
|
520
525
|
Description: Checks for `instance_double` used with `have_received`.
|
@@ -725,6 +730,12 @@ RSpec/ReceiveCounts:
|
|
725
730
|
VersionAdded: '1.26'
|
726
731
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReceiveCounts
|
727
732
|
|
733
|
+
RSpec/ReceiveMessages:
|
734
|
+
Description: Checks for multiple messages stubbed on the same object.
|
735
|
+
Enabled: pending
|
736
|
+
VersionAdded: '2.23'
|
737
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReceiveMessages
|
738
|
+
|
728
739
|
RSpec/ReceiveNever:
|
729
740
|
Description: Prefer `not_to receive(...)` over `receive(...).never`.
|
730
741
|
Enabled: true
|
@@ -974,11 +985,11 @@ RSpec/FactoryBot/AttributeDefinedStatically:
|
|
974
985
|
Description: Always declare attribute values as blocks.
|
975
986
|
Enabled: true
|
976
987
|
Include:
|
977
|
-
- spec/factories.rb
|
978
|
-
- spec/factories/**/*.rb
|
979
|
-
- features/support/factories/**/*.rb
|
988
|
+
- "**/spec/factories.rb"
|
989
|
+
- "**/spec/factories/**/*.rb"
|
990
|
+
- "**/features/support/factories/**/*.rb"
|
980
991
|
VersionAdded: '1.28'
|
981
|
-
VersionChanged: '2.
|
992
|
+
VersionChanged: '2.23'
|
982
993
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/AttributeDefinedStatically
|
983
994
|
|
984
995
|
RSpec/FactoryBot/ConsistentParenthesesStyle:
|
@@ -997,26 +1008,26 @@ RSpec/FactoryBot/CreateList:
|
|
997
1008
|
Include:
|
998
1009
|
- "**/*_spec.rb"
|
999
1010
|
- "**/spec/**/*"
|
1000
|
-
- spec/factories.rb
|
1001
|
-
- spec/factories/**/*.rb
|
1002
|
-
- features/support/factories/**/*.rb
|
1011
|
+
- "**/spec/factories.rb"
|
1012
|
+
- "**/spec/factories/**/*.rb"
|
1013
|
+
- "**/features/support/factories/**/*.rb"
|
1003
1014
|
EnforcedStyle: create_list
|
1004
1015
|
SupportedStyles:
|
1005
1016
|
- create_list
|
1006
1017
|
- n_times
|
1007
1018
|
VersionAdded: '1.25'
|
1008
|
-
VersionChanged: '2.
|
1019
|
+
VersionChanged: '2.23'
|
1009
1020
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/CreateList
|
1010
1021
|
|
1011
1022
|
RSpec/FactoryBot/FactoryClassName:
|
1012
1023
|
Description: Use string value when setting the class attribute explicitly.
|
1013
1024
|
Enabled: true
|
1014
1025
|
Include:
|
1015
|
-
- spec/factories.rb
|
1016
|
-
- spec/factories/**/*.rb
|
1017
|
-
- features/support/factories/**/*.rb
|
1026
|
+
- "**/spec/factories.rb"
|
1027
|
+
- "**/spec/factories/**/*.rb"
|
1028
|
+
- "**/features/support/factories/**/*.rb"
|
1018
1029
|
VersionAdded: '1.37'
|
1019
|
-
VersionChanged: '2.
|
1030
|
+
VersionChanged: '2.23'
|
1020
1031
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/FactoryClassName
|
1021
1032
|
|
1022
1033
|
RSpec/FactoryBot/FactoryNameStyle:
|
@@ -1095,6 +1106,16 @@ RSpec/Rails/MinitestAssertions:
|
|
1095
1106
|
VersionAdded: '2.17'
|
1096
1107
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/MinitestAssertions
|
1097
1108
|
|
1109
|
+
RSpec/Rails/NegationBeValid:
|
1110
|
+
Description: Enforces use of `be_invalid` or `not_to` for negated be_valid.
|
1111
|
+
EnforcedStyle: not_to
|
1112
|
+
SupportedStyles:
|
1113
|
+
- not_to
|
1114
|
+
- be_invalid
|
1115
|
+
Enabled: pending
|
1116
|
+
VersionAdded: '2.23'
|
1117
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/NegationBeValid
|
1118
|
+
|
1098
1119
|
RSpec/Rails/TravelAround:
|
1099
1120
|
Description: Prefer to travel in `before` rather than `around`.
|
1100
1121
|
Enabled: pending
|
data/config/obsoletion.yml
CHANGED
@@ -21,3 +21,9 @@ renamed:
|
|
21
21
|
RSpec/Capybara/SpecificFinders: Capybara/SpecificFinders
|
22
22
|
RSpec/Capybara/SpecificMatcher: Capybara/SpecificMatcher
|
23
23
|
RSpec/Capybara/VisibilityMatcher: Capybara/VisibilityMatcher
|
24
|
+
RSpec/FactoryBot/AttributeDefinedStatically: FactoryBot/AttributeDefinedStatically
|
25
|
+
RSpec/FactoryBot/ConsistentParenthesesStyle: FactoryBot/ConsistentParenthesesStyle
|
26
|
+
RSpec/FactoryBot/CreateList: FactoryBot/CreateList
|
27
|
+
RSpec/FactoryBot/FactoryClassName: FactoryBot/FactoryClassName
|
28
|
+
RSpec/FactoryBot/FactoryNameStyle: FactoryBot/FactoryNameStyle
|
29
|
+
RSpec/FactoryBot/SyntaxMethods: FactoryBot/SyntaxMethods
|
@@ -131,6 +131,7 @@ module RuboCop
|
|
131
131
|
{
|
132
132
|
#examples_directly_or_in_block?
|
133
133
|
(begin <#examples_directly_or_in_block? ...>)
|
134
|
+
(begin <#examples_in_branches? ...>)
|
134
135
|
}
|
135
136
|
PATTERN
|
136
137
|
|
@@ -169,6 +170,8 @@ module RuboCop
|
|
169
170
|
end
|
170
171
|
|
171
172
|
def examples_in_branches?(condition_node)
|
173
|
+
return if !condition_node.if_type? && !condition_node.case_type?
|
174
|
+
|
172
175
|
condition_node.branches.any? { |branch| examples?(branch) }
|
173
176
|
end
|
174
177
|
|
@@ -52,14 +52,21 @@ module RuboCop
|
|
52
52
|
|
53
53
|
# @param text [String]
|
54
54
|
def excessive_whitespace?(text)
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
text.match?(/
|
56
|
+
# Leading space
|
57
|
+
\A[[:blank:]]
|
58
|
+
|
|
59
|
+
# Trailing space
|
60
|
+
[[:blank:]]\z
|
61
|
+
|
|
62
|
+
# Two or more consecutive spaces, except if they are leading spaces
|
63
|
+
[^[[:space:]]][[:blank:]]{2,}[^[[:blank:]]]
|
64
|
+
/x)
|
58
65
|
end
|
59
66
|
|
60
67
|
# @param text [String]
|
61
68
|
def strip_excessive_whitespace(text)
|
62
|
-
text.strip.gsub(/
|
69
|
+
text.strip.gsub(/[[:blank:]]{2,}/, ' ')
|
63
70
|
end
|
64
71
|
|
65
72
|
# @param node [RuboCop::AST::Node]
|
@@ -24,7 +24,7 @@ module RuboCop
|
|
24
24
|
class ExpectActual < Base
|
25
25
|
extend AutoCorrector
|
26
26
|
|
27
|
-
MSG = 'Provide the actual you are testing to `expect(...)`.'
|
27
|
+
MSG = 'Provide the actual value you are testing to `expect(...)`.'
|
28
28
|
|
29
29
|
RESTRICT_ON_SEND = Runners.all
|
30
30
|
|
@@ -77,7 +77,7 @@ module RuboCop
|
|
77
77
|
|
78
78
|
private
|
79
79
|
|
80
|
-
# This is not
|
80
|
+
# This is not implemented using a NodePattern because it seems
|
81
81
|
# to not be able to match against an explicit (nil) sexp
|
82
82
|
def literal?(node)
|
83
83
|
node && (simple_literal?(node) || complex_literal?(node))
|
@@ -4,124 +4,31 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module RSpec
|
6
6
|
module FactoryBot
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# #
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# #
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# #
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# #
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# #
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# #
|
26
|
-
#
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
# @!method value_matcher(node)
|
34
|
-
def_node_matcher :value_matcher, <<-PATTERN
|
35
|
-
(send _ !#reserved_method? $...)
|
36
|
-
PATTERN
|
37
|
-
|
38
|
-
# @!method factory_attributes(node)
|
39
|
-
def_node_matcher :factory_attributes, <<-PATTERN
|
40
|
-
(block (send _ #attribute_defining_method? ...) _ { (begin $...) $(send ...) } )
|
41
|
-
PATTERN
|
42
|
-
|
43
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
44
|
-
attributes = factory_attributes(node) || []
|
45
|
-
attributes = [attributes] unless attributes.is_a?(Array) # rubocop:disable Style/ArrayCoercion, Lint/RedundantCopDisableDirective
|
46
|
-
|
47
|
-
attributes.each do |attribute|
|
48
|
-
next unless offensive_receiver?(attribute.receiver, node)
|
49
|
-
next if proc?(attribute) || association?(attribute.first_argument)
|
50
|
-
|
51
|
-
add_offense(attribute) do |corrector|
|
52
|
-
autocorrect(corrector, attribute)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def autocorrect(corrector, node)
|
60
|
-
if node.parenthesized?
|
61
|
-
autocorrect_replacing_parens(corrector, node)
|
62
|
-
else
|
63
|
-
autocorrect_without_parens(corrector, node)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def offensive_receiver?(receiver, node)
|
68
|
-
receiver.nil? ||
|
69
|
-
receiver.self_type? ||
|
70
|
-
receiver_matches_first_block_argument?(receiver, node)
|
71
|
-
end
|
72
|
-
|
73
|
-
def receiver_matches_first_block_argument?(receiver, node)
|
74
|
-
first_block_argument = node.arguments.first
|
75
|
-
|
76
|
-
!first_block_argument.nil? &&
|
77
|
-
receiver.lvar_type? &&
|
78
|
-
receiver.node_parts == first_block_argument.node_parts
|
79
|
-
end
|
80
|
-
|
81
|
-
def proc?(attribute)
|
82
|
-
value_matcher(attribute).to_a.all?(&:block_pass_type?)
|
83
|
-
end
|
84
|
-
|
85
|
-
# @!method association?(node)
|
86
|
-
def_node_matcher :association?, '(hash <(pair (sym :factory) _) ...>)'
|
87
|
-
|
88
|
-
def autocorrect_replacing_parens(corrector, node)
|
89
|
-
left_braces, right_braces = braces(node)
|
90
|
-
|
91
|
-
corrector.replace(node.location.begin, " #{left_braces}")
|
92
|
-
corrector.replace(node.location.end, right_braces)
|
93
|
-
end
|
94
|
-
|
95
|
-
def autocorrect_without_parens(corrector, node)
|
96
|
-
left_braces, right_braces = braces(node)
|
97
|
-
|
98
|
-
argument = node.first_argument
|
99
|
-
expression = argument.source_range
|
100
|
-
corrector.insert_before(expression, left_braces)
|
101
|
-
corrector.insert_after(expression, right_braces)
|
102
|
-
end
|
103
|
-
|
104
|
-
def braces(node)
|
105
|
-
if value_hash_without_braces?(node.first_argument)
|
106
|
-
['{ { ', ' } }']
|
107
|
-
else
|
108
|
-
['{ ', ' }']
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def value_hash_without_braces?(node)
|
113
|
-
node.hash_type? && !node.braces?
|
114
|
-
end
|
115
|
-
|
116
|
-
def reserved_method?(method_name)
|
117
|
-
RuboCop::RSpec::FactoryBot.reserved_methods.include?(method_name)
|
118
|
-
end
|
119
|
-
|
120
|
-
def attribute_defining_method?(method_name)
|
121
|
-
RuboCop::RSpec::FactoryBot.attribute_defining_methods
|
122
|
-
.include?(method_name)
|
123
|
-
end
|
124
|
-
end
|
7
|
+
# @!parse
|
8
|
+
# # Always declare attribute values as blocks.
|
9
|
+
# #
|
10
|
+
# # @example
|
11
|
+
# # # bad
|
12
|
+
# # kind [:active, :rejected].sample
|
13
|
+
# #
|
14
|
+
# # # good
|
15
|
+
# # kind { [:active, :rejected].sample }
|
16
|
+
# #
|
17
|
+
# # # bad
|
18
|
+
# # closed_at 1.day.from_now
|
19
|
+
# #
|
20
|
+
# # # good
|
21
|
+
# # closed_at { 1.day.from_now }
|
22
|
+
# #
|
23
|
+
# # # bad
|
24
|
+
# # count 1
|
25
|
+
# #
|
26
|
+
# # # good
|
27
|
+
# # count { 1 }
|
28
|
+
# #
|
29
|
+
# class AttributeDefinedStatically < ::RuboCop::Cop::Base; end
|
30
|
+
AttributeDefinedStatically =
|
31
|
+
::RuboCop::Cop::FactoryBot::AttributeDefinedStatically
|
125
32
|
end
|
126
33
|
end
|
127
34
|
end
|
@@ -4,113 +4,46 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module RSpec
|
6
6
|
module FactoryBot
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# #
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# create
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# #
|
20
|
-
#
|
21
|
-
# create(:user)
|
22
|
-
# create(:
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
# #
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# create :login
|
32
|
-
#
|
33
|
-
# #
|
34
|
-
# #
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
include RuboCop::Cop::Util
|
48
|
-
|
49
|
-
def self.autocorrect_incompatible_with
|
50
|
-
[Style::MethodCallWithArgsParentheses]
|
51
|
-
end
|
52
|
-
|
53
|
-
MSG_REQUIRE_PARENS = 'Prefer method call with parentheses'
|
54
|
-
MSG_OMIT_PARENS = 'Prefer method call without parentheses'
|
55
|
-
|
56
|
-
FACTORY_CALLS = RuboCop::RSpec::FactoryBot::Language::METHODS
|
57
|
-
|
58
|
-
RESTRICT_ON_SEND = FACTORY_CALLS
|
59
|
-
|
60
|
-
# @!method factory_call(node)
|
61
|
-
def_node_matcher :factory_call, <<-PATTERN
|
62
|
-
(send
|
63
|
-
{#factory_bot? nil?} %FACTORY_CALLS
|
64
|
-
{sym str send lvar} _*
|
65
|
-
)
|
66
|
-
PATTERN
|
67
|
-
|
68
|
-
def on_send(node)
|
69
|
-
return if ambiguous_without_parentheses?(node)
|
70
|
-
|
71
|
-
factory_call(node) do
|
72
|
-
return if node.method?(:generate) && node.arguments.count > 1
|
73
|
-
|
74
|
-
if node.parenthesized?
|
75
|
-
process_with_parentheses(node)
|
76
|
-
else
|
77
|
-
process_without_parentheses(node)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
private
|
83
|
-
|
84
|
-
def process_with_parentheses(node)
|
85
|
-
return unless style == :omit_parentheses
|
86
|
-
return unless same_line?(node, node.first_argument)
|
87
|
-
|
88
|
-
add_offense(node.loc.selector,
|
89
|
-
message: MSG_OMIT_PARENS) do |corrector|
|
90
|
-
remove_parentheses(corrector, node)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def process_without_parentheses(node)
|
95
|
-
return unless style == :require_parentheses
|
96
|
-
|
97
|
-
add_offense(node.loc.selector,
|
98
|
-
message: MSG_REQUIRE_PARENS) do |corrector|
|
99
|
-
add_parentheses(node, corrector)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
AMBIGUOUS_TYPES = %i[send pair array and or if].freeze
|
104
|
-
|
105
|
-
def ambiguous_without_parentheses?(node)
|
106
|
-
node.parent && AMBIGUOUS_TYPES.include?(node.parent.type)
|
107
|
-
end
|
108
|
-
|
109
|
-
def remove_parentheses(corrector, node)
|
110
|
-
corrector.replace(node.location.begin, ' ')
|
111
|
-
corrector.remove(node.location.end)
|
112
|
-
end
|
113
|
-
end
|
7
|
+
# @!parse
|
8
|
+
# # Use a consistent style for parentheses in factory bot calls.
|
9
|
+
# #
|
10
|
+
# # @example
|
11
|
+
# #
|
12
|
+
# # # bad
|
13
|
+
# # create :user
|
14
|
+
# # build(:user)
|
15
|
+
# # create(:login)
|
16
|
+
# # create :login
|
17
|
+
# #
|
18
|
+
# # @example `EnforcedStyle: require_parentheses` (default)
|
19
|
+
# #
|
20
|
+
# # # good
|
21
|
+
# # create(:user)
|
22
|
+
# # create(:user)
|
23
|
+
# # create(:login)
|
24
|
+
# # build(:login)
|
25
|
+
# #
|
26
|
+
# # @example `EnforcedStyle: omit_parentheses`
|
27
|
+
# #
|
28
|
+
# # # good
|
29
|
+
# # create :user
|
30
|
+
# # build :user
|
31
|
+
# # create :login
|
32
|
+
# # create :login
|
33
|
+
# #
|
34
|
+
# # # also good
|
35
|
+
# # # when method name and first argument are not on same line
|
36
|
+
# # create(
|
37
|
+
# # :user
|
38
|
+
# # )
|
39
|
+
# # build(
|
40
|
+
# # :user,
|
41
|
+
# # name: 'foo'
|
42
|
+
# # )
|
43
|
+
# #
|
44
|
+
# class ConsistentParenthesesStyle < ::RuboCop::Cop::Base; end
|
45
|
+
ConsistentParenthesesStyle =
|
46
|
+
::RuboCop::Cop::FactoryBot::ConsistentParenthesesStyle
|
114
47
|
end
|
115
48
|
end
|
116
49
|
end
|