class RuboCop::Cop::RSpec::RepeatedSubjectCall


end
expect { subject.b }.to not_change { A.count }
expect { subject.a }.to change { A.count }
it do
# also good
end
expect { my_method }.to not_change { A.count }
expect { my_method }.to change { A.count }
it do
# good
end
expect { subject }.to not_change { A.count }
expect { subject }.to change { A.count }
it do
end
expect { subject }.to not_change { A.count }
subject
it do
# bad
@example
Checks for repeated calls to subject missing that it is memoized.

def detect_offense(subject_node)

def detect_offense(subject_node)
  return if subject_node.chained?
  return if subject_node.parent.send_type?
  return unless (block_node = expect_block(subject_node))
  add_offense(block_node)
end

def detect_offenses_in_block(node, subject_names = [])

def detect_offenses_in_block(node, subject_names = [])
  subject_names = [*subject_names, *@subjects_by_node[node]]
  if example?(node)
    return detect_offenses_in_example(node, subject_names)
  end
  node.each_child_node(:send, :def, :block, :begin) do |child|
    detect_offenses_in_block(child, subject_names)
  end
end

def detect_offenses_in_example(node, subject_names)

def detect_offenses_in_example(node, subject_names)
  return unless node.body
  subjects_used = Hash.new(false)
  subject_calls(node.body, Set[*subject_names, :subject]).each do |call|
    if subjects_used[call.method_name]
      detect_offense(call)
    else
      subjects_used[call.method_name] = true
    end
  end
end

def detect_subjects_in_scope(node)

def detect_subjects_in_scope(node)
  node.each_descendant(:block).with_object({}) do |child, h|
    subject?(child) do |name|
      outer_example_group = child.each_ancestor(:block).find do |a|
        example_group?(a)
      end
      (h[outer_example_group] ||= []) << name
    end
  end
end

def expect_block(node)

def expect_block(node)
  node.each_ancestor(:block).find { |block| block.method?(:expect) }
end

def on_top_level_group(node)

def on_top_level_group(node)
  @subjects_by_node = detect_subjects_in_scope(node)
  detect_offenses_in_block(node)
end