From e5a086f6dbd8c30dbf0ffed4a939cab08f3f4805 Mon Sep 17 00:00:00 2001 From: Juan Vasquez Date: Mon, 9 Oct 2023 18:15:03 -0600 Subject: [PATCH] Fix Instance Variable Assumption false positive Fixes #1492 --- .../instance_variable_assumption.rb | 16 ++++++------- .../instance_variable_assumption_spec.rb | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/reek/smell_detectors/instance_variable_assumption.rb b/lib/reek/smell_detectors/instance_variable_assumption.rb index 52ac46d36..1f7083d07 100644 --- a/lib/reek/smell_detectors/instance_variable_assumption.rb +++ b/lib/reek/smell_detectors/instance_variable_assumption.rb @@ -20,7 +20,7 @@ def self.contexts # @return [Array] # def sniff - assumptions = (variables_from_context - variables_from_initialize).uniq + assumptions = (variables_from_context - variables_from_initializers).uniq assumptions.map do |assumption| build_smell_warning(assumption) @@ -42,14 +42,14 @@ def build_smell_warning(assumption) parameters: { assumption: assumption.to_s }) end - def variables_from_initialize - initialize_exp = method_expressions.detect do |method| - method.name == :initialize - end - - return [] unless initialize_exp + def variables_from_initializers + variables_from_initialize.map do |method| + method.each_node(:ivasgn).map(&:name) + end.flatten + end - initialize_exp.each_node(:ivasgn).map(&:name) + def variables_from_initialize + method_expressions.select { |method| method.name == :initialize } end def variables_from_context diff --git a/spec/reek/smell_detectors/instance_variable_assumption_spec.rb b/spec/reek/smell_detectors/instance_variable_assumption_spec.rb index 3f7ed83c8..a75b392cc 100644 --- a/spec/reek/smell_detectors/instance_variable_assumption_spec.rb +++ b/spec/reek/smell_detectors/instance_variable_assumption_spec.rb @@ -93,4 +93,27 @@ def delta expect(src).to reek_of(:InstanceVariableAssumption, context: 'Alfa::Charlie') end + + it 'does not report when the initialize is in a nested Struct class' do + src = <<-RUBY + class Foo + Bar = Struct.new(:status) do + def initialize(status) + super + p 'bar created' + end + end + + def initialize + @foo = :foo + end + + def foo? + @foo == :foo + end + end + RUBY + + expect(src).not_to reek_of(:InstanceVariableAssumption) + end end