Add :: to namespace the module we delegate "to"

Only namespace when the delegation object is a module
This commit is contained in:
George Ma 2024-01-30 10:54:37 -05:00 committed by Jean Boussier
parent b16b5168af
commit 3711c69ab0
2 changed files with 40 additions and 1 deletions

@ -39,7 +39,19 @@ def generate(owner, methods, location: nil, to: nil, prefix: nil, allow_nil: nil
location ||= caller_locations(1, 1).first
file, line = location.path, location.lineno
receiver = to.to_s
receiver = if to.is_a?(Module)
if to.name.nil?
raise ArgumentError, "Can't delegate to anonymous class or module: #{to}"
end
unless Inflector.safe_constantize(to.name).equal?(to)
raise ArgumentError, "Can't delegate to detached class or module: #{to.name}"
end
"::#{to.name}"
else
to.to_s
end
receiver = "self.#{receiver}" if RESERVED_METHOD_NAMES.include?(receiver)
explicit_receiver = false

@ -586,6 +586,33 @@ def initialize(place)
location.delegate(:street, :city, to: :@place, prefix: :the, private: true)
end
def test_module_nesting_is_empty
# Ensure constant resolution is done from top level namespace and not ActiveSupport
require "json"
c = Class.new do
singleton_class.delegate :parse, to: ::JSON
end
assert_equal [1], c.parse("[1]")
end
def test_delegation_unreacheable_module
anonymous_class = Class.new
error = assert_raises ArgumentError do
Class.new do
delegate :something, to: anonymous_class
end
end
assert_includes error.message, "Can't delegate to anonymous class or module"
anonymous_class.singleton_class.define_method(:name) { "FakeName" }
error = assert_raises ArgumentError do
Class.new do
delegate :something, to: anonymous_class
end
end
assert_includes error.message, "Can't delegate to detached class or module: FakeName"
end
def test_delegation_arity_to_module
c = Class.new do
delegate :zero, :one, :two, to: ArityTester