rubocop-factory_bot 2.23.1 → 2.26.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d8a45a48d47318e9e16e7b3bbde99ae9dcf94f6e90c068f0916ff2945511e85
4
- data.tar.gz: 52ff0ffe8fb20bc0ed3ec4dca29aa13a29b106e39f7bacac370388f0c789bf1c
3
+ metadata.gz: 60519b0d051edd3ba23a10f3dfb346dc5aaed4964c489bcfabdb7d16c084cb63
4
+ data.tar.gz: effac41ed4215d5cb27295cdb0a37d8c7021c309e97a8f8e6f8fdf6e385e8226
5
5
  SHA512:
6
- metadata.gz: 53082b6baa7e6ebe69f3ebcc1404f2c8421bfcd3ee6905eba12789faca59c1c090b84abc4696a0773598ab06eb97e8aa2b70384864376b58e568d9eef5ce2549
7
- data.tar.gz: 26f1817b168218b61f7657400f777ec5eb972cedab14501b2f6a5b1bd8691af9b4c3b04607969923eb58ffca49e4070622040950a7d00742624d4d5b03cf9ee1
6
+ metadata.gz: ee33ad705e93ffa3a68240adabd9de50735819d4d82bbf66868f2efa80d489a0032fd045878bf8fd539dc7677fed9bbf9ef0e3755340b81b4fc1881220e0b24c
7
+ data.tar.gz: 89936fe77a9c8f3ff5dad656b9e30455ec2f6467ac7cba1c678e63fca22396825c3859bc1830f6e766a90109cbae3eca68f64d5a110e3bbd8cebd229cf3218e9
data/CHANGELOG.md CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 2.26.1 (2024-06-12)
6
+
7
+ - Bump RuboCop requirement to +1.61. ([@ydah])
8
+
9
+ ## 2.26.0 (2024-06-08)
10
+
11
+ - Fix a false positive for `FactoryBot/AssociationStyle` when using nested factories with traits. ([@jaydorsey])
12
+ - Support `AutoCorrect: contextual` option for LSP. ([@ydah])
13
+
14
+ ## 2.25.1 (2024-01-08)
15
+
16
+ - Fix a false positive for `FactoryBot/CreateList` when create call does have method calls and repeat multiple times with other argument. ([@ydah])
17
+ - Fix an error occurred for `FactoryBot/IdSequence` when `sequence` with non-symbol argument or without argument. ([@ydah])
18
+
19
+ ## 2.25.0 (2024-01-04)
20
+
21
+ - Fix a false positive for `FactoryBot/FactoryNameStyle` when namespaced models. ([@ydah])
22
+ - Add new `FactoryBot/ExcessiveCreateList` cop. ([@ddieulivol])
23
+ - Fix a false positive for `FactoryBot/ConsistentParenthesesStyle` when hash pinning. ([@ydah])
24
+
25
+ ## 2.24.0 (2023-09-18)
26
+
27
+ - Fix `FactoryBot/AssociationStyle` cop to ignore explicit associations with `strategy: :build`. ([@pirj])
28
+ - Change `FactoryBot/CreateList` so that it is not an offense if not repeated multiple times. ([@ydah])
29
+ - Fix a false positive for `FactoryBot/AssociationStyle` when `association` is called in trait block and column name is keyword. ([@ydah])
30
+ - Fix a false positive for `FactoryBot/AssociationStyle` when `EnforcedStyle: Explicit` and using trait within trait. ([@ydah])
31
+ - Change `FactoryBot/AssociationStyle`, `FactoryBot/AttributeDefinedStatically`, `FactoryBot/CreateList` and `FactoryBot/FactoryClassName` to work with minitest style directory. ([@ydah])
32
+ - Add `FactoryBot/IdSequence` cop. ([@owst])
33
+
5
34
  ## 2.23.1 (2023-05-15)
6
35
 
7
36
  - Fix `FactoryBot/AssociationStyle` cop for a blockless `factory`. ([@pirj])
@@ -22,7 +51,7 @@
22
51
 
23
52
  ## Previously (see [rubocop-rspec's changelist](https://github.com/rubocop/rubocop-rspec/blob/70a97b1895ce4b9bcd6ff336d5d343ddc6175fe6/CHANGELOG.md) for details)
24
53
 
25
- - Fix a false positive for `RSpec/FactoryBot/ConsistentParenthesesStyle` inside `&&`, `||` and `:?` when `omit_parentheses` is on ([@dmitrytsepelev])
54
+ - Fix a false positive for `RSpec/FactoryBot/ConsistentParenthesesStyle` inside `&&`, `||` and `:?` when `omit_parentheses` is on. ([@dmitrytsepelev])
26
55
  - Add new `RSpec/FactoryBot/FactoryNameStyle` cop. ([@ydah])
27
56
  - Fix wrong autocorrection in `n_times` style on `RSpec/FactoryBot/CreateList`. ([@r7kamura])
28
57
  - Fix a false positive for `RSpec/FactoryBot/ConsistentParenthesesStyle` when using `generate` with multiple arguments. ([@ydah])
@@ -65,14 +94,17 @@
65
94
  [@bquorning]: https://github.com/bquorning
66
95
  [@composerinteralia]: https://github.com/composerinteralia
67
96
  [@darhazer]: https://github.com/Darhazer
97
+ [@ddieulivol]: https://github.com/ddieulivol
68
98
  [@dmitrytsepelev]: https://github.com/dmitrytsepelev
69
99
  [@harrylewis]: https://github.com/harrylewis
100
+ [@jaydorsey]: https://github.com/jaydorsey
70
101
  [@jfragoulis]: https://github.com/jfragoulis
71
102
  [@jonatas]: https://github.com/jonatas
72
103
  [@leoarnold]: https://github.com/leoarnold
73
104
  [@liberatys]: https://github.com/Liberatys
74
105
  [@morissetcl]: https://github.com/morissetcl
75
106
  [@ngouy]: https://github.com/ngouy
107
+ [@owst]: https://github.com/owst
76
108
  [@pirj]: https://github.com/pirj
77
109
  [@r7kamura]: https://github.com/r7kamura
78
110
  [@seanpdoyle]: https://github.com/seanpdoyle
data/config/default.yml CHANGED
@@ -2,9 +2,10 @@
2
2
  FactoryBot:
3
3
  Enabled: true
4
4
  Include:
5
- - "**/*_spec.rb"
6
- - "**/spec/**/*"
7
- - "**/test/**/*"
5
+ - "**/spec/factories.rb"
6
+ - "**/spec/factories/**/*.rb"
7
+ - "**/test/factories.rb"
8
+ - "**/test/factories/**/*.rb"
8
9
  - "**/features/support/factories/**/*.rb"
9
10
  DocumentationBaseURL: https://docs.rubocop.org/rubocop-factory_bot
10
11
 
@@ -12,11 +13,8 @@ FactoryBot/AssociationStyle:
12
13
  Description: Use a consistent style to define associations.
13
14
  Enabled: pending
14
15
  Safe: false
15
- Include:
16
- - spec/factories.rb
17
- - spec/factories/**/*.rb
18
- - features/support/factories/**/*.rb
19
16
  VersionAdded: '2.23'
17
+ VersionChanged: '2.24'
20
18
  EnforcedStyle: implicit
21
19
  SupportedStyles:
22
20
  - explicit
@@ -27,17 +25,18 @@ FactoryBot/AssociationStyle:
27
25
  FactoryBot/AttributeDefinedStatically:
28
26
  Description: Always declare attribute values as blocks.
29
27
  Enabled: true
30
- Include:
31
- - spec/factories.rb
32
- - spec/factories/**/*.rb
33
- - features/support/factories/**/*.rb
34
28
  VersionAdded: '1.28'
35
- VersionChanged: '2.0'
29
+ VersionChanged: '2.24'
36
30
  Reference: https://www.rubydoc.info/gems/rubocop-factory_bot/RuboCop/Cop/FactoryBot/AttributeDefinedStatically
37
31
 
38
32
  FactoryBot/ConsistentParenthesesStyle:
39
33
  Description: Use a consistent style for parentheses in factory_bot calls.
40
34
  Enabled: pending
35
+ Include:
36
+ - "**/*_spec.rb"
37
+ - "**/spec/**/*"
38
+ - "**/test/**/*"
39
+ - "**/features/support/factories/**/*.rb"
41
40
  EnforcedStyle: require_parentheses
42
41
  SupportedStyles:
43
42
  - require_parentheses
@@ -50,12 +49,12 @@ FactoryBot/ConsistentParenthesesStyle:
50
49
  FactoryBot/CreateList:
51
50
  Description: Checks for create_list usage.
52
51
  Enabled: true
52
+ AutoCorrect: contextual
53
53
  Include:
54
54
  - "**/*_spec.rb"
55
55
  - "**/spec/**/*"
56
- - spec/factories.rb
57
- - spec/factories/**/*.rb
58
- - features/support/factories/**/*.rb
56
+ - "**/test/**/*"
57
+ - "**/features/support/factories/**/*.rb"
59
58
  EnforcedStyle: create_list
60
59
  SupportedStyles:
61
60
  - create_list
@@ -63,12 +62,29 @@ FactoryBot/CreateList:
63
62
  ExplicitOnly: false
64
63
  SafeAutoCorrect: false
65
64
  VersionAdded: '1.25'
66
- VersionChanged: '2.23'
65
+ VersionChanged: '2.26'
67
66
  Reference: https://www.rubydoc.info/gems/rubocop-factory_bot/RuboCop/Cop/FactoryBot/CreateList
68
67
 
68
+ FactoryBot/ExcessiveCreateList:
69
+ Description: Check for excessive model creation in a list.
70
+ Enabled: pending
71
+ Include:
72
+ - "**/*_spec.rb"
73
+ - "**/spec/**/*"
74
+ - "**/test/**/*"
75
+ - "**/features/support/factories/**/*.rb"
76
+ MaxAmount: 10
77
+ VersionAdded: '2.25'
78
+ Reference: https://www.rubydoc.info/gems/rubocop-factory_bot/RuboCop/Cop/FactoryBot/ExcessiveCreateList
79
+
69
80
  FactoryBot/FactoryAssociationWithStrategy:
70
81
  Description: Use definition in factory association instead of hard coding a strategy.
71
82
  Enabled: pending
83
+ Include:
84
+ - "**/*_spec.rb"
85
+ - "**/spec/**/*"
86
+ - "**/test/**/*"
87
+ - "**/features/support/factories/**/*.rb"
72
88
  VersionAdded: '2.23'
73
89
  VersionChanged: '2.23'
74
90
  Reference: https://www.rubydoc.info/gems/rubocop-factory_bot/RuboCop/Cop/FactoryBot/FactoryAssociationWithStrategy
@@ -76,17 +92,18 @@ FactoryBot/FactoryAssociationWithStrategy:
76
92
  FactoryBot/FactoryClassName:
77
93
  Description: Use string value when setting the class attribute explicitly.
78
94
  Enabled: true
79
- Include:
80
- - spec/factories.rb
81
- - spec/factories/**/*.rb
82
- - features/support/factories/**/*.rb
83
95
  VersionAdded: '1.37'
84
- VersionChanged: '2.0'
96
+ VersionChanged: '2.24'
85
97
  Reference: https://www.rubydoc.info/gems/rubocop-factory_bot/RuboCop/Cop/FactoryBot/FactoryClassName
86
98
 
87
99
  FactoryBot/FactoryNameStyle:
88
100
  Description: Checks for name style for argument of FactoryBot::Syntax::Methods.
89
101
  Enabled: pending
102
+ Include:
103
+ - "**/*_spec.rb"
104
+ - "**/spec/**/*"
105
+ - "**/test/**/*"
106
+ - "**/features/support/factories/**/*.rb"
90
107
  EnforcedStyle: symbol
91
108
  SupportedStyles:
92
109
  - symbol
@@ -96,15 +113,31 @@ FactoryBot/FactoryNameStyle:
96
113
  VersionChanged: '2.23'
97
114
  Reference: https://www.rubydoc.info/gems/rubocop-factory_bot/RuboCop/Cop/FactoryBot/FactoryNameStyle
98
115
 
116
+ FactoryBot/IdSequence:
117
+ Description: Do not create a FactoryBot sequence for an id column.
118
+ Enabled: pending
119
+ VersionAdded: '2.24'
120
+ Reference: https://www.rubydoc.info/gems/rubocop-factory_bot/RuboCop/Cop/FactoryBot/IdSequence
121
+
99
122
  FactoryBot/RedundantFactoryOption:
100
123
  Description: Checks for redundant `factory` option.
101
124
  Enabled: pending
125
+ Include:
126
+ - "**/*_spec.rb"
127
+ - "**/spec/**/*"
128
+ - "**/test/**/*"
129
+ - "**/features/support/factories/**/*.rb"
102
130
  VersionAdded: '2.23'
103
131
  Reference: https://www.rubydoc.info/gems/rubocop-factory_bot/RuboCop/Cop/FactoryBot/RedundantFactoryOption
104
132
 
105
133
  FactoryBot/SyntaxMethods:
106
134
  Description: Use shorthands from `FactoryBot::Syntax::Methods` in your specs.
107
135
  Enabled: pending
136
+ Include:
137
+ - "**/*_spec.rb"
138
+ - "**/spec/**/*"
139
+ - "**/test/**/*"
140
+ - "**/features/support/factories/**/*.rb"
108
141
  SafeAutoCorrect: false
109
142
  VersionAdded: '2.7'
110
143
  Reference: https://www.rubydoc.info/gems/rubocop-factory_bot/RuboCop/Cop/FactoryBot/SyntaxMethods
@@ -21,6 +21,16 @@ module RuboCop
21
21
  # user
22
22
  # end
23
23
  #
24
+ # # bad
25
+ # factory :post do
26
+ # association :user, :author
27
+ # end
28
+ #
29
+ # # good
30
+ # factory :post do
31
+ # user factory: %i[user author]
32
+ # end
33
+ #
24
34
  # @example EnforcedStyle: explicit
25
35
  # # bad
26
36
  # factory :post do
@@ -32,6 +42,16 @@ module RuboCop
32
42
  # association :user
33
43
  # end
34
44
  #
45
+ # # bad
46
+ # factory :post do
47
+ # user factory: %i[user author]
48
+ # end
49
+ #
50
+ # # good
51
+ # factory :post do
52
+ # association :user, :author
53
+ # end
54
+ #
35
55
  # # good (NonImplicitAssociationMethodNames: ['email'])
36
56
  # sequence :email do |n|
37
57
  # "person#{n}@example.com"
@@ -47,12 +67,18 @@ module RuboCop
47
67
 
48
68
  DEFAULT_NON_IMPLICIT_ASSOCIATION_METHOD_NAMES = %w[
49
69
  association
70
+ factory
50
71
  sequence
51
72
  skip_create
52
73
  traits_for_enum
53
74
  ].freeze
54
75
 
55
76
  RESTRICT_ON_SEND = %i[factory trait].freeze
77
+ KEYWORDS = %i[alias and begin break case class def defined? do
78
+ else elsif end ensure false for if in module
79
+ next nil not or redo rescue retry return self
80
+ super then true undef unless until when while
81
+ yield __FILE__ __LINE__ __ENCODING__].freeze
56
82
 
57
83
  def on_send(node)
58
84
  bad_associations_in(node).each do |association|
@@ -72,6 +98,13 @@ module RuboCop
72
98
  (send nil? :association sym ...)
73
99
  PATTERN
74
100
 
101
+ # @!method with_strategy_build_option?(node)
102
+ def_node_matcher :with_strategy_build_option?, <<~PATTERN
103
+ (send nil? :association sym ...
104
+ (hash <(pair (sym :strategy) (sym :build)) ...>)
105
+ )
106
+ PATTERN
107
+
75
108
  # @!method implicit_association?(node)
76
109
  def_node_matcher :implicit_association?, <<~PATTERN
77
110
  (send nil? !#non_implicit_association_method_name? ...)
@@ -103,6 +136,16 @@ module RuboCop
103
136
  (send nil? :association _ (sym $_)* ...)
104
137
  PATTERN
105
138
 
139
+ # @!method association_names(node)
140
+ def_node_search :association_names, <<~PATTERN
141
+ (send nil? :association $...)
142
+ PATTERN
143
+
144
+ # @!method trait_name(node)
145
+ def_node_search :trait_name, <<~PATTERN
146
+ (send nil? :trait (sym $_) )
147
+ PATTERN
148
+
106
149
  def autocorrect(corrector, node)
107
150
  if style == :explicit
108
151
  autocorrect_to_explicit_style(corrector, node)
@@ -131,9 +174,22 @@ module RuboCop
131
174
 
132
175
  def bad?(node)
133
176
  if style == :explicit
134
- implicit_association?(node)
177
+ implicit_association?(node) &&
178
+ !trait_within_trait?(node)
135
179
  else
136
- explicit_association?(node)
180
+ explicit_association?(node) &&
181
+ !with_strategy_build_option?(node) &&
182
+ !keyword?(node)
183
+ end
184
+ end
185
+
186
+ def keyword?(node)
187
+ association_names(node).any? do |associations|
188
+ associations.any? do |association|
189
+ next unless association.sym_type?
190
+
191
+ KEYWORDS.include?(association.value)
192
+ end
137
193
  end
138
194
  end
139
195
 
@@ -190,6 +246,14 @@ module RuboCop
190
246
  end
191
247
  options
192
248
  end
249
+
250
+ def trait_within_trait?(node)
251
+ factory_node = node.ancestors.reverse.find do |ancestor|
252
+ ancestor.method?(:factory) if ancestor.block_type?
253
+ end
254
+
255
+ trait_name(factory_node).include?(node.method_name)
256
+ end
193
257
  end
194
258
  end
195
259
  end
@@ -70,7 +70,7 @@ module RuboCop
70
70
  end
71
71
 
72
72
  def receiver_matches_first_block_argument?(receiver, node)
73
- first_block_argument = node.arguments.first
73
+ first_block_argument = node.first_argument
74
74
 
75
75
  !first_block_argument.nil? &&
76
76
  receiver.lvar_type? &&
@@ -75,6 +75,17 @@ module RuboCop
75
75
  )
76
76
  PATTERN
77
77
 
78
+ # @!method omit_hash_value?(node)
79
+ def_node_matcher :omit_hash_value?, <<~PATTERN
80
+ (send
81
+ #factory_call? %FACTORY_CALLS
82
+ {sym str send lvar}
83
+ (hash
84
+ <value_omission? ...>
85
+ )
86
+ )
87
+ PATTERN
88
+
78
89
  def self.autocorrect_incompatible_with
79
90
  [Style::MethodCallWithArgsParentheses]
80
91
  end
@@ -97,6 +108,7 @@ module RuboCop
97
108
  def register_offense_with_parentheses(node)
98
109
  return if style == :require_parentheses || !node.parenthesized?
99
110
  return unless same_line?(node, node.first_argument)
111
+ return if omit_hash_value?(node)
100
112
 
101
113
  add_offense(node.loc.selector,
102
114
  message: MSG_OMIT_PARENS) do |corrector|
@@ -58,7 +58,7 @@ module RuboCop
58
58
  # create_list :user, 3
59
59
  # 3.times { create :user }
60
60
  #
61
- class CreateList < ::RuboCop::Cop::Base
61
+ class CreateList < ::RuboCop::Cop::Base # rubocop:disable Metrics/ClassLength
62
62
  extend AutoCorrector
63
63
  include ConfigurableEnforcedStyle
64
64
  include RuboCop::FactoryBot::Language
@@ -68,24 +68,15 @@ module RuboCop
68
68
  MSG_N_TIMES = 'Prefer %<number>s.times.map.'
69
69
  RESTRICT_ON_SEND = %i[create_list].freeze
70
70
 
71
- # @!method repetition_block?(node)
72
- def_node_matcher :repetition_block?, <<-PATTERN
73
- (block {#array_new? #n_times? #n_times_map?} ...)
74
- PATTERN
75
-
76
- # @!method array_new?(node)
77
- def_node_matcher :array_new?, <<-PATTERN
78
- (send (const {nil? cbase} :Array) :new (int _))
79
- PATTERN
80
-
81
- # @!method n_times?(node)
82
- def_node_matcher :n_times?, <<-PATTERN
83
- (send (int _) :times)
84
- PATTERN
85
-
86
- # @!method n_times_map?(node)
87
- def_node_matcher :n_times_map?, <<-PATTERN
88
- (send #n_times? :map)
71
+ # @!method repeat_count(node)
72
+ def_node_matcher :repeat_count, <<~PATTERN
73
+ (block
74
+ {
75
+ (send (const {nil? cbase} :Array) :new (int $_)) # Array.new(3) { create(:user) }
76
+ (send (int $_) :times) # 3.times { create(:user) }
77
+ (send (send (int $_) :times) :map) # 3.times.map { create(:user) }
78
+ }
79
+ ...)
89
80
  PATTERN
90
81
 
91
82
  # @!method block_with_arg_and_used?(node)
@@ -99,7 +90,7 @@ module RuboCop
99
90
 
100
91
  # @!method arguments_include_method_call?(node)
101
92
  def_node_matcher :arguments_include_method_call?, <<~PATTERN
102
- (send #factory_call? :create sym `$(send ...))
93
+ (send #factory_call? :create sym ... `(send ...))
103
94
  PATTERN
104
95
 
105
96
  # @!method factory_call(node)
@@ -113,12 +104,13 @@ module RuboCop
113
104
  PATTERN
114
105
 
115
106
  # @!method factory_calls_in_array?(node)
116
- def_node_search :factory_calls_in_array?, <<-PATTERN
107
+ def_node_search :factory_calls_in_array?, <<~PATTERN
117
108
  (array #factory_call+)
118
109
  PATTERN
119
110
 
120
111
  def on_array(node)
121
112
  return unless same_factory_calls_in_array?(node)
113
+ return if node.values.size < 2
122
114
 
123
115
  add_offense(
124
116
  node,
@@ -128,10 +120,9 @@ module RuboCop
128
120
  end
129
121
  end
130
122
 
131
- def on_block(node) # rubocop:todo InternalAffairs/NumblockHandler
123
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, Metrics/CyclomaticComplexity
132
124
  return unless style == :create_list
133
-
134
- return unless repetition_block?(node)
125
+ return unless repeat_multiple_time?(node)
135
126
  return if block_with_arg_and_used?(node)
136
127
  return unless node.body
137
128
  return if arguments_include_method_call?(node.body)
@@ -146,6 +137,8 @@ module RuboCop
146
137
  return unless style == :n_times
147
138
 
148
139
  factory_list_call(node) do |count|
140
+ next if count < 2
141
+
149
142
  message = format(MSG_N_TIMES, number: count)
150
143
  add_offense(node.loc.selector, message: message) do |corrector|
151
144
  TimesCorrector.new(node).call(corrector)
@@ -155,6 +148,12 @@ module RuboCop
155
148
 
156
149
  private
157
150
 
151
+ def repeat_multiple_time?(node)
152
+ return false unless (count = repeat_count(node))
153
+
154
+ count > 1
155
+ end
156
+
158
157
  # For ease of modification, it is replaced with the `n_times` style,
159
158
  # but if it is not appropriate for the configured style,
160
159
  # it will be replaced in the subsequent autocorrection.
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module FactoryBot
6
+ # Check for excessive model creation in a list.
7
+ #
8
+ # @example MaxAmount: 10 (default)
9
+ # # We do not allow more than 10 items to be created
10
+ #
11
+ # # bad
12
+ # create_list(:merge_request, 1000, state: :opened)
13
+ #
14
+ # # good
15
+ # create_list(:merge_request, 10, state: :opened)
16
+ #
17
+ # @example MaxAmount: 20
18
+ # # We do not allow more than 20 items to be created
19
+ #
20
+ # # bad
21
+ # create_list(:merge_request, 1000, state: :opened)
22
+ #
23
+ # # good
24
+ # create_list(:merge_request, 15, state: :opened)
25
+ #
26
+ class ExcessiveCreateList < ::RuboCop::Cop::Base
27
+ include ConfigurableExplicitOnly
28
+
29
+ MESSAGE =
30
+ 'Avoid using `create_list` with more than %<max_amount>s items.'
31
+
32
+ # @!method create_list?(node)
33
+ def_node_matcher :create_list?, <<~PATTERN
34
+ (send #factory_call? :create_list {sym str} $(int _) ...)
35
+ PATTERN
36
+
37
+ RESTRICT_ON_SEND = %i[create_list].freeze
38
+
39
+ def on_send(node)
40
+ number_node = create_list?(node)
41
+ return unless number_node
42
+
43
+ max_amount = cop_config['MaxAmount']
44
+ return if number_node.value <= max_amount
45
+
46
+ add_offense(number_node, message:
47
+ format(MESSAGE, max_amount: max_amount))
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -14,6 +14,9 @@ module RuboCop
14
14
  # create(:user)
15
15
  # build :user, username: "NAME"
16
16
  #
17
+ # # good - namespaced models
18
+ # create('users/internal')
19
+ #
17
20
  # @example EnforcedStyle: string
18
21
  # # bad
19
22
  # create(:user)
@@ -76,13 +79,17 @@ module RuboCop
76
79
  private
77
80
 
78
81
  def offense_for_symbol_style?(name)
79
- name.str_type? && style == :symbol
82
+ name.str_type? && style == :symbol && !namespaced?(name)
80
83
  end
81
84
 
82
85
  def offense_for_string_style?(name)
83
86
  name.sym_type? && style == :string
84
87
  end
85
88
 
89
+ def namespaced?(name)
90
+ name.value.include?('/')
91
+ end
92
+
86
93
  def register_offense(name, prefer)
87
94
  add_offense(name,
88
95
  message: format(MSG, prefer: style.to_s)) do |corrector|
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module FactoryBot
6
+ # Do not create a FactoryBot sequence for an id column.
7
+ #
8
+ # @example
9
+ # # bad - can lead to conflicts between FactoryBot and DB sequences
10
+ # factory :foo do
11
+ # sequence :id
12
+ # end
13
+ #
14
+ # # good - a non-id column
15
+ # factory :foo do
16
+ # sequence :some_non_id_column
17
+ # end
18
+ #
19
+ class IdSequence < ::RuboCop::Cop::Base
20
+ extend AutoCorrector
21
+ include RangeHelp
22
+ include RuboCop::FactoryBot::Language
23
+
24
+ MSG = 'Do not create a sequence for an id attribute'
25
+ RESTRICT_ON_SEND = %i[sequence].freeze
26
+
27
+ def on_send(node)
28
+ return unless node.receiver.nil? || factory_bot?(node.receiver)
29
+ return unless node.first_argument&.sym_type? &&
30
+ node.first_argument.value == :id
31
+
32
+ add_offense(node) do |corrector|
33
+ range_to_remove = range_by_whole_lines(
34
+ node.source_range,
35
+ include_final_newline: true
36
+ )
37
+
38
+ corrector.remove(range_to_remove)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -4,8 +4,10 @@ require_relative 'factory_bot/association_style'
4
4
  require_relative 'factory_bot/attribute_defined_statically'
5
5
  require_relative 'factory_bot/consistent_parentheses_style'
6
6
  require_relative 'factory_bot/create_list'
7
+ require_relative 'factory_bot/excessive_create_list'
7
8
  require_relative 'factory_bot/factory_association_with_strategy'
8
9
  require_relative 'factory_bot/factory_class_name'
9
10
  require_relative 'factory_bot/factory_name_style'
11
+ require_relative 'factory_bot/id_sequence'
10
12
  require_relative 'factory_bot/redundant_factory_option'
11
13
  require_relative 'factory_bot/syntax_methods'
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module FactoryBot
5
+ module Cop
6
+ # Source and spec generator for new cops
7
+ #
8
+ # This generator will take a cop name and generate a source file
9
+ # and spec file when given a valid qualified cop name.
10
+ # @api private
11
+ class Generator < RuboCop::Cop::Generator
12
+ def todo
13
+ <<~TODO
14
+ Do 4 steps:
15
+ 1. Modify the description of #{badge} in config/default.yml
16
+ 2. Implement your new cop in the generated file!
17
+ 3. Add an entry about new cop to CHANGELOG.md
18
+ 4. Commit your new cop with a message such as
19
+ e.g. "Add new `#{badge}` cop"
20
+ TODO
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module FactoryBot
5
5
  # Version information for the factory_bot RuboCop plugin.
6
6
  module Version
7
- STRING = '2.23.1'
7
+ STRING = '2.26.1'
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-factory_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.23.1
4
+ version: 2.26.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Backus
@@ -9,10 +9,10 @@ authors:
9
9
  - Phil Pirozhkov
10
10
  - Maxim Krizhanovsky
11
11
  - Andrew Bromwich
12
- autorequire:
12
+ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2023-05-16 00:00:00.000000000 Z
15
+ date: 2024-06-11 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rubocop
@@ -20,18 +20,18 @@ dependencies:
20
20
  requirements:
21
21
  - - "~>"
22
22
  - !ruby/object:Gem::Version
23
- version: '1.33'
23
+ version: '1.61'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
28
  - - "~>"
29
29
  - !ruby/object:Gem::Version
30
- version: '1.33'
30
+ version: '1.61'
31
31
  description: |
32
32
  Code style checking for factory_bot files.
33
33
  A plugin for the RuboCop code style enforcing & linting tool.
34
- email:
34
+ email:
35
35
  executables: []
36
36
  extensions: []
37
37
  extra_rdoc_files:
@@ -48,14 +48,17 @@ files:
48
48
  - lib/rubocop/cop/factory_bot/attribute_defined_statically.rb
49
49
  - lib/rubocop/cop/factory_bot/consistent_parentheses_style.rb
50
50
  - lib/rubocop/cop/factory_bot/create_list.rb
51
+ - lib/rubocop/cop/factory_bot/excessive_create_list.rb
51
52
  - lib/rubocop/cop/factory_bot/factory_association_with_strategy.rb
52
53
  - lib/rubocop/cop/factory_bot/factory_class_name.rb
53
54
  - lib/rubocop/cop/factory_bot/factory_name_style.rb
55
+ - lib/rubocop/cop/factory_bot/id_sequence.rb
54
56
  - lib/rubocop/cop/factory_bot/mixin/configurable_explicit_only.rb
55
57
  - lib/rubocop/cop/factory_bot/redundant_factory_option.rb
56
58
  - lib/rubocop/cop/factory_bot/syntax_methods.rb
57
59
  - lib/rubocop/cop/factory_bot_cops.rb
58
60
  - lib/rubocop/factory_bot/config_formatter.rb
61
+ - lib/rubocop/factory_bot/cop/generator.rb
59
62
  - lib/rubocop/factory_bot/description_extractor.rb
60
63
  - lib/rubocop/factory_bot/factory_bot.rb
61
64
  - lib/rubocop/factory_bot/language.rb
@@ -67,7 +70,7 @@ metadata:
67
70
  changelog_uri: https://github.com/rubocop/rubocop-factory_bot/blob/master/CHANGELOG.md
68
71
  documentation_uri: https://docs.rubocop.org/rubocop-factory_bot/
69
72
  rubygems_mfa_required: 'true'
70
- post_install_message:
73
+ post_install_message:
71
74
  rdoc_options: []
72
75
  require_paths:
73
76
  - lib
@@ -82,8 +85,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
85
  - !ruby/object:Gem::Version
83
86
  version: '0'
84
87
  requirements: []
85
- rubygems_version: 3.4.13
86
- signing_key:
88
+ rubygems_version: 3.5.9
89
+ signing_key:
87
90
  specification_version: 4
88
91
  summary: Code style checking for factory_bot files
89
92
  test_files: []