rubocop-rspec 2.21.0 → 2.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/README.md +1 -1
  4. data/config/default.yml +37 -16
  5. data/config/obsoletion.yml +6 -0
  6. data/lib/rubocop/cop/rspec/empty_example_group.rb +3 -0
  7. data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +11 -4
  8. data/lib/rubocop/cop/rspec/expect_actual.rb +2 -2
  9. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +25 -118
  10. data/lib/rubocop/cop/rspec/factory_bot/consistent_parentheses_style.rb +40 -107
  11. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +30 -250
  12. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +19 -46
  13. data/lib/rubocop/cop/rspec/factory_bot/factory_name_style.rb +23 -64
  14. data/lib/rubocop/cop/rspec/factory_bot/syntax_methods.rb +45 -79
  15. data/lib/rubocop/cop/rspec/focus.rb +13 -0
  16. data/lib/rubocop/cop/rspec/indexed_let.rb +32 -1
  17. data/lib/rubocop/cop/rspec/instance_variable.rb +1 -1
  18. data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +1 -1
  19. data/lib/rubocop/cop/rspec/let_before_examples.rb +4 -0
  20. data/lib/rubocop/cop/rspec/named_subject.rb +1 -1
  21. data/lib/rubocop/cop/rspec/pending.rb +12 -2
  22. data/lib/rubocop/cop/rspec/predicate_matcher.rb +3 -3
  23. data/lib/rubocop/cop/rspec/rails/negation_be_valid.rb +92 -0
  24. data/lib/rubocop/cop/rspec/receive_messages.rb +155 -0
  25. data/lib/rubocop/cop/rspec/verified_double_reference.rb +1 -1
  26. data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -1
  27. data/lib/rubocop/cop/rspec_cops.rb +2 -0
  28. data/lib/rubocop/rspec/config_formatter.rb +6 -0
  29. data/lib/rubocop/rspec/version.rb +1 -1
  30. data/lib/rubocop-rspec.rb +1 -3
  31. metadata +18 -4
  32. data/lib/rubocop/rspec/factory_bot/language.rb +0 -37
  33. data/lib/rubocop/rspec/factory_bot.rb +0 -64
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a388b40471f85e4da35358c9c9c0ab8bdce272c171b989553a174ea5f2fa04f
4
- data.tar.gz: 251c7b2c7f83daeb4f3e3f4e10f1b0f37763088ac792982e27052da26c1645ea
3
+ metadata.gz: e0eebbfb772c1598b0ee4cfe88c74d8b81171e197dbd4d5dc6020df95005440e
4
+ data.tar.gz: 2936be502e0062b94a0346bd98696194fd33fe6f7693f8c92bc38a952ee31b26
5
5
  SHA512:
6
- metadata.gz: 6311a48d125da92639f8bebbeebdd9b16e7968bf2b522d29310c913490977a465aa77112e39497880373be23732a2fb3cfa205b92475e2edd069c1009ae91aac
7
- data.tar.gz: fd3d495d5ec63969e2d926c5c151cf888de321b74486644983c6aa72b3c18b071daafe19b0996a0fa476334d00bf05768c09ae4ce03d39bbdf436898b64809c0
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
@@ -17,7 +17,7 @@ gem install rubocop-rspec
17
17
 
18
18
  or if you use bundler put this in your `Gemfile`
19
19
 
20
- ```
20
+ ```ruby
21
21
  gem 'rubocop-rspec', require: false
22
22
  ```
23
23
 
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.0'
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.0'
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.0'
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
@@ -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
- return true if text.start_with?(' ') || text.end_with?(' ')
56
-
57
- text.match?(/[^\n ] +[^ ]/)
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 implement using a NodePattern because it seems
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
- # Always declare attribute values as blocks.
8
- #
9
- # @example
10
- # # bad
11
- # kind [:active, :rejected].sample
12
- #
13
- # # good
14
- # kind { [:active, :rejected].sample }
15
- #
16
- # # bad
17
- # closed_at 1.day.from_now
18
- #
19
- # # good
20
- # closed_at { 1.day.from_now }
21
- #
22
- # # bad
23
- # count 1
24
- #
25
- # # good
26
- # count { 1 }
27
- #
28
- class AttributeDefinedStatically < ::RuboCop::Cop::Base
29
- extend AutoCorrector
30
-
31
- MSG = 'Use a block to declare attribute values.'
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
- # Use a consistent style for parentheses in factory bot calls.
8
- #
9
- # @example
10
- #
11
- # # bad
12
- # create :user
13
- # build(:user)
14
- # create(:login)
15
- # create :login
16
- #
17
- # @example `EnforcedStyle: require_parentheses` (default)
18
- #
19
- # # good
20
- # create(:user)
21
- # create(:user)
22
- # create(:login)
23
- # build(:login)
24
- #
25
- # @example `EnforcedStyle: omit_parentheses`
26
- #
27
- # # good
28
- # create :user
29
- # build :user
30
- # create :login
31
- # create :login
32
- #
33
- # # also good
34
- # # when method name and first argument are not on same line
35
- # create(
36
- # :user
37
- # )
38
- # build(
39
- # :user,
40
- # name: 'foo'
41
- # )
42
- #
43
- class ConsistentParenthesesStyle < ::RuboCop::Cop::Base
44
- extend AutoCorrector
45
- include ConfigurableEnforcedStyle
46
- include RuboCop::RSpec::FactoryBot::Language
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