class RubyIndexer::EnhancementTest

def test_advancing_namespace_stack_from_enhancement

def test_advancing_namespace_stack_from_enhancement
  Class.new(Enhancement) do
    def on_call_node_enter(call_node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
      owner = @listener.current_owner
      return unless owner
      case call_node.name
      when :class_methods
        @listener.add_module("ClassMethods", call_node.location, call_node.location)
      when :extend
        arguments = call_node.arguments&.arguments
        return unless arguments
        arguments.each do |node|
          next unless node.is_a?(Prism::ConstantReadNode) || node.is_a?(Prism::ConstantPathNode)
          module_name = node.full_name
          next unless module_name == "ActiveSupport::Concern"
          @listener.register_included_hook do |index, base|
            class_methods_name = "#{owner.name}::ClassMethods"
            if index.indexed?(class_methods_name)
              singleton = index.existing_or_new_singleton_class(base.name)
              singleton.mixin_operations << Entry::Include.new(class_methods_name)
            end
          end
        end
      end
    end
    def on_call_node_leave(call_node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
      return unless call_node.name == :class_methods
      @listener.pop_namespace_stack
    end
  end
  index(<<~RUBY)
    module ActiveSupport
      module Concern
      end
    end
    module MyConcern
      extend ActiveSupport::Concern
      class_methods do
        def foo; end
      end
    end
    class User
      include MyConcern
    end
  RUBY
  assert_equal(
    [
      "User::<Class:User>",
      "MyConcern::ClassMethods",
      "Object::<Class:Object>",
      "BasicObject::<Class:BasicObject>",
      "Class",
      "Module",
      "Object",
      "Kernel",
      "BasicObject",
    ],
    @index.linearized_ancestors_of("User::<Class:User>"),
  )
  refute_nil(@index.resolve_method("foo", "User::<Class:User>"))
end