diff --git a/CHANGELOG.md b/CHANGELOG.md index a5b4bbaa..b54e54bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Fix a false positive for `FactoryBot/FactoryNameStyle` when namespaced models. ([@ydah]) - Add new `FactoryBot/ExcessiveCreateList` cop. ([@ddieulivol]) +- Fix a false positive for `FactoryBot/ConsistentParenthesesStyle` when hash pinning. ([@ydah]) ## 2.24.0 (2023-09-18) diff --git a/lib/rubocop/cop/factory_bot/consistent_parentheses_style.rb b/lib/rubocop/cop/factory_bot/consistent_parentheses_style.rb index fd86f441..1a346ce2 100644 --- a/lib/rubocop/cop/factory_bot/consistent_parentheses_style.rb +++ b/lib/rubocop/cop/factory_bot/consistent_parentheses_style.rb @@ -75,6 +75,17 @@ class ConsistentParenthesesStyle < ::RuboCop::Cop::Base ) PATTERN + # @!method omit_hash_value?(node) + def_node_matcher :omit_hash_value?, <<~PATTERN + (send + #factory_call? %FACTORY_CALLS + {sym str send lvar} + (hash + + ) + ) + PATTERN + def self.autocorrect_incompatible_with [Style::MethodCallWithArgsParentheses] end @@ -97,6 +108,7 @@ def register_offense(node) def register_offense_with_parentheses(node) return if style == :require_parentheses || !node.parenthesized? return unless same_line?(node, node.first_argument) + return if omit_hash_value?(node) add_offense(node.loc.selector, message: MSG_OMIT_PARENS) do |corrector| diff --git a/spec/rubocop/cop/factory_bot/consistent_parentheses_style_spec.rb b/spec/rubocop/cop/factory_bot/consistent_parentheses_style_spec.rb index 0b220488..6719fe84 100644 --- a/spec/rubocop/cop/factory_bot/consistent_parentheses_style_spec.rb +++ b/spec/rubocop/cop/factory_bot/consistent_parentheses_style_spec.rb @@ -405,6 +405,48 @@ generate(:foo, :bar) RUBY end + + context 'when TargetRubyVersion >= 3.1', :ruby31 do + it 'does not register an offense when using `create` ' \ + 'with pinned hash argument' do + expect_no_offenses(<<~RUBY) + create(:user, name:) + create(:user, name:, client:) + RUBY + end + + it 'does not register an offense when using `create` ' \ + 'with pinned hash argument and other unpinned args' do + expect_no_offenses(<<~RUBY) + create(:user, client:, name: 'foo') + create(:user, client: 'foo', name:) + RUBY + end + + it 'registers an offense when using `create` ' \ + 'with unpinned hash argument' do + expect_offense(<<~RUBY) + create(:user, name: 'foo') + ^^^^^^ Prefer method call without parentheses + RUBY + + expect_correction(<<~RUBY) + create :user, name: 'foo' + RUBY + end + + it 'registers an offense when using `create` ' \ + 'with method call has pinned hash argument' do + expect_offense(<<~RUBY) + create(:user, foo(name:)) + ^^^^^^ Prefer method call without parentheses + RUBY + + expect_correction(<<~RUBY) + create :user, foo(name:) + RUBY + end + end end context 'when ExplicitOnly is false' do