Skip to content

Commit af3f62e

Browse files
ngouypirj
authored andcommitted
[Fix #1087] Ignore CreateList offense on method call detection
1 parent 426513d commit af3f62e

File tree

4 files changed

+57
-10
lines changed

4 files changed

+57
-10
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Fix incorrect path suggested by `RSpec/FilePath` cop when second argument contains spaces. ([@tejasbubane][])
66
* Fix autocorrect for EmptyLineSeparation. ([@johnny-miyake][])
77
* Add new `RSpec/Capybara/SpecificMatcher` cop. ([@ydah][])
8+
* Fixed false offense detection in `FactoryBot/CreateList` when a n.times block is including method calls in the factory create arguments. ([@ngouy][])
89

910
## 2.11.1 (2022-05-18)
1011

@@ -699,3 +700,4 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
699700
[@M-Yamashita01]: https://github.com/M-Yamashita01
700701
[@luke-hill]: https://github.com/luke-hill
701702
[@johnny-miyake]: https://github.com/johnny-miyake
703+
[@ngouy]: https://github.com/ngouy

docs/modules/ROOT/pages/cops_rspec_factorybot.adoc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,14 @@ This cop can be configured using the `EnforcedStyle` option
7979
# good
8080
create_list :user, 3
8181
82-
# good
83-
3.times { |n| create :user, created_at: n.months.ago }
82+
# bad
83+
3.times { create :user, age: 18 }
84+
85+
# good - index is used to alter the created models attributes
86+
3.times { |n| create :user, age: n }
87+
88+
# good - contains a method call, may return different values
89+
3.times { create :user, age: rand }
8490
----
8591

8692
==== `EnforcedStyle: n_times`

lib/rubocop/cop/rspec/factory_bot/create_list.rb

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,14 @@ module FactoryBot
1515
# # good
1616
# create_list :user, 3
1717
#
18-
# # good
19-
# 3.times { |n| create :user, created_at: n.months.ago }
18+
# # bad
19+
# 3.times { create :user, age: 18 }
20+
#
21+
# # good - index is used to alter the created models attributes
22+
# 3.times { |n| create :user, age: n }
23+
#
24+
# # good - contains a method call, may return different values
25+
# 3.times { create :user, age: rand }
2026
#
2127
# @example `EnforcedStyle: n_times`
2228
# # bad
@@ -33,15 +39,28 @@ class CreateList < Base
3339
MSG_N_TIMES = 'Prefer %<number>s.times.'
3440
RESTRICT_ON_SEND = %i[create_list].freeze
3541

36-
# @!method n_times_block_without_arg?(node)
37-
def_node_matcher :n_times_block_without_arg?, <<-PATTERN
42+
# @!method n_times_block?(node)
43+
def_node_matcher :n_times_block?, <<-PATTERN
3844
(block
3945
(send (int _) :times)
40-
(args)
4146
...
4247
)
4348
PATTERN
4449

50+
# @!method n_times_block_with_arg_and_used?(node)
51+
def_node_matcher :n_times_block_with_arg_and_used?, <<-PATTERN
52+
(block
53+
(send (int _) :times)
54+
(args (arg _value))
55+
`_value
56+
)
57+
PATTERN
58+
59+
# @!method arguments_include_method_call?(node)
60+
def_node_matcher :arguments_include_method_call?, <<-PATTERN
61+
(send ${nil? #factory_bot?} :create (sym $_) `$(send ...))
62+
PATTERN
63+
4564
# @!method factory_call(node)
4665
def_node_matcher :factory_call, <<-PATTERN
4766
(send ${nil? #factory_bot?} :create (sym $_) $...)
@@ -54,7 +73,10 @@ class CreateList < Base
5473

5574
def on_block(node)
5675
return unless style == :create_list
57-
return unless n_times_block_without_arg?(node)
76+
77+
return unless n_times_block?(node)
78+
return if n_times_block_with_arg_and_used?(node)
79+
return if arguments_include_method_call?(node.body)
5880
return unless contains_only_factory?(node.body)
5981

6082
add_offense(node.send_node, message: MSG_CREATE_LIST) do |corrector|

spec/rubocop/cop/rspec/factory_bot/create_list_spec.rb

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,26 @@
5353
RUBY
5454
end
5555

56-
it 'ignores n.times with argument' do
56+
it 'ignores n.times with n as argument' do
5757
expect_no_offenses(<<~RUBY)
58-
3.times { |n| create :user, created_at: n.days.ago }
58+
3.times { |n| create :user, position: n }
59+
RUBY
60+
end
61+
62+
it 'flags n.times when create call doesn\'t have method calls' do
63+
expect_offense(<<~RUBY)
64+
3.times { |n| create :user, :active }
65+
^^^^^^^ Prefer create_list.
66+
3.times { |n| create :user, password: '123' }
67+
^^^^^^^ Prefer create_list.
68+
3.times { |n| create :user, :active, password: '123' }
69+
^^^^^^^ Prefer create_list.
70+
RUBY
71+
end
72+
73+
it 'ignores n.times when create call does have method calls' do
74+
expect_no_offenses(<<~RUBY)
75+
3.times { |n| create :user, repositories_count: rand }
5976
RUBY
6077
end
6178

0 commit comments

Comments
 (0)