From e3bcf91bb9e9d4eaa785fe745ebf9b7d410009fa Mon Sep 17 00:00:00 2001 From: Bill Ruddock Date: Mon, 13 Jul 2020 22:52:39 +0100 Subject: [PATCH] Fix move namespaced constant in Style/ConditionalAssignment Fix autocorrect for moving constant assignment outside the condition when the constant is in a namespace, e.g. from: ```ruby condition ? FOO::BAR = 1 : FOO::BAR = 2 if condition ::FOO = 1 else ::FOO = 2 end ``` to keep the namespace `Foo::` and the top-level `::` in correction: ```ruby FOO::BAR = cond? ? 1 : 2 ::FOO = if condition 1 else 2 end ``` --- CHANGELOG.md | 1 + .../cop/style/conditional_assignment.rb | 11 +++++- ...nal_assignment_assign_to_condition_spec.rb | 38 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb880c433a6..751287b34db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Bug fixes * [#8324](https://github.com/rubocop-hq/rubocop/issues/8324): Fix crash for `Layout/SpaceAroundMethodCallOperator` when using `Proc#call` shorthand syntax. ([@fatkodima][]) +* [#8332](https://github.com/rubocop-hq/rubocop/pull/8332): Fix auto-correct in `Style/ConditionalAssignment` to preserve constant namespace. ([@biinari][]) ## 0.88.0 (2020-07-13) diff --git a/lib/rubocop/cop/style/conditional_assignment.rb b/lib/rubocop/cop/style/conditional_assignment.rb index 42e2488a5a0..ae8bbbbf0e7 100644 --- a/lib/rubocop/cop/style/conditional_assignment.rb +++ b/lib/rubocop/cop/style/conditional_assignment.rb @@ -43,7 +43,7 @@ def lhs(node) when :and_asgn, :or_asgn "#{node.children[0].source} #{node.loc.operator.source} " when :casgn - "#{node.children[1]} = " + lhs_for_casgn(node) when *ConditionalAssignment::VARIABLE_ASSIGNMENT_TYPES "#{node.children[0]} = " else @@ -93,6 +93,15 @@ def lhs_for_send(node) end end + def lhs_for_casgn(node) + namespace = node.children[0] + if namespace.nil? || namespace.cbase_type? + "#{namespace&.source}#{node.children[1]} = " + else + "#{namespace.source}::#{node.children[1]} = " + end + end + def setter_method?(method_name) method_name.to_s.end_with?(EQUAL) && !%i[!= == === >= <=].include?(method_name) diff --git a/spec/rubocop/cop/style/conditional_assignment_assign_to_condition_spec.rb b/spec/rubocop/cop/style/conditional_assignment_assign_to_condition_spec.rb index d0f3cb88508..dbf2a153329 100644 --- a/spec/rubocop/cop/style/conditional_assignment_assign_to_condition_spec.rb +++ b/spec/rubocop/cop/style/conditional_assignment_assign_to_condition_spec.rb @@ -1563,6 +1563,44 @@ end end + context 'constant assignment' do + it 'corrects if..else with namespaced constant' do + expect_offense(<<~RUBY) + if something + ^^^^^^^^^^^^ Use the return of the conditional for variable assignment and comparison. + FOO::BAR = 1 + else + FOO::BAR = 2 + end + RUBY + expect_correction(<<~RUBY) + FOO::BAR = if something + 1 + else + 2 + end + RUBY + end + + it 'corrects if..else with top-level constant' do + expect_offense(<<~RUBY) + if something + ^^^^^^^^^^^^ Use the return of the conditional for variable assignment and comparison. + ::BAR = 1 + else + ::BAR = 2 + end + RUBY + expect_correction(<<~RUBY) + ::BAR = if something + 1 + else + 2 + end + RUBY + end + end + context 'self.attribute= assignment' do it 'corrects if..else' do expect_offense(<<~RUBY)