Skip to content

Commit

Permalink
Fix a false positive for FactoryBot/AssociationStyle when `associat…
Browse files Browse the repository at this point in the history
…ion` is called in trait block and column name is keyword

Fix: #58
  • Loading branch information
ydah committed Jul 5, 2023
1 parent afc310e commit ec4e156
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Fix `FactoryBot/AssociationStyle` cop to ignore explicit associations with `strategy: :build`. ([@pirj])
- Change `FactoryBot/CreateList` so that it is not an offense if not repeated multiple times. ([@ydah])
- Fix a false positive for `FactoryBot/AssociationStyle` when `association` is called in trait block and column name is keyword. ([@ydah])

## 2.23.1 (2023-05-15)

Expand Down
23 changes: 22 additions & 1 deletion lib/rubocop/cop/factory_bot/association_style.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class AssociationStyle < ::RuboCop::Cop::Base # rubocop:disable Metrics/ClassLen
].freeze

RESTRICT_ON_SEND = %i[factory trait].freeze
KEYWORDS = %i[alias and begin break case class def defined? do
else elsif end ensure false for if in module
next nil not or redo rescue retry return self
super then true undef unless until when while
yield __FILE__ __LINE__ __ENCODING__].freeze

def on_send(node)
bad_associations_in(node).each do |association|
Expand Down Expand Up @@ -130,6 +135,11 @@ def on_send(node)
(send nil? :association _ (sym $_)* ...)
PATTERN

# @!method association_names(node)
def_node_search :association_names, <<~PATTERN
(send nil? :association $...)
PATTERN

def autocorrect(corrector, node)
if style == :explicit
autocorrect_to_explicit_style(corrector, node)
Expand Down Expand Up @@ -161,7 +171,18 @@ def bad?(node)
implicit_association?(node)
else
explicit_association?(node) &&
!with_strategy_build_option?(node)
!with_strategy_build_option?(node) &&
!keyword?(node)
end
end

def keyword?(node)
association_names(node).any? do |associations|
associations.any? do |association|
next unless association.sym_type?

KEYWORDS.include?(association.value)
end
end
end

Expand Down
43 changes: 43 additions & 0 deletions spec/rubocop/cop/factory_bot/association_style_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,49 @@ def inspected_source_filename
RUBY
end
end

context 'when `association` is called in trait block ' \
'and column name is keyword' do
it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
factory :article do
trait :with_class do
association :alias
association :and, factory: :user
association :foo, :__FILE__
end
end
RUBY
end
end

context 'when `association` is called in trait block ' \
'and factory option is keyword' do
it 'registers and corrects an offense' do
expect_offense(<<~RUBY)
factory :article do
trait :with_class do
association :foo, factory: :alias
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use implicit style to define associations.
association :bar, factory: :and
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use implicit style to define associations.
association :baz, factory: :__FILE__
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use implicit style to define associations.
end
end
RUBY

expect_correction(<<~RUBY)
factory :article do
trait :with_class do
foo factory: %i[alias]
bar factory: %i[and]
baz factory: %i[__FILE__]
end
end
RUBY
end
end
end

context 'when EnforcedStyle is :explicit' do
Expand Down

0 comments on commit ec4e156

Please sign in to comment.