diff --git a/lib/ams/delegatable.rb b/lib/ams/delegatable.rb index 4ef27bda..afaf4829 100644 --- a/lib/ams/delegatable.rb +++ b/lib/ams/delegatable.rb @@ -1,5 +1,7 @@ module AMS module Delegatable + KERNEL_METHOD_METHOD = ::Kernel.instance_method(:method) + # delegate constant lookup to Object def const_missing(name) ::Object.const_get(name) @@ -12,6 +14,10 @@ module AMS __send__(*args) end + def method(method_name) + AMS::Delegatable::KERNEL_METHOD_METHOD.bind(self).call(method_name) + end + private def method_missing(name, *args, &block) @@ -21,16 +27,6 @@ module AMS def respond_to_missing?(name, include_private = false) object.respond_to?(name, include_private) end - - const_set(:KERNEL_METHOD_METHOD, ::Kernel.instance_method(:method)) - def method_handle_for(method_name) - KERNEL_METHOD_METHOD.bind(self).call(method_name) - rescue NameError => original - handle = self.method(method_name) - raise original unless handle.is_a? Method - handle - end - alias method method_handle_for end end end diff --git a/test/unit/serializer/object_delegation_test.rb b/test/unit/serializer/object_delegation_test.rb index 2c25b681..1d03d849 100644 --- a/test/unit/serializer/object_delegation_test.rb +++ b/test/unit/serializer/object_delegation_test.rb @@ -5,6 +5,7 @@ module AMS class Serializer class ObjectDelegationTest < Test class ParentModelSerializer < Serializer + attribute :some_method end def setup @@ -26,6 +27,29 @@ module AMS def test_model_delegates_respond_to_object refute @serializer_instance.respond_to?(:not_delegated?) end + + def test_model_delegates_respond_to_missing_to_object + refute @serializer_instance.respond_to?(:not_delegated?) + end + + def test_serializer_binds_method_method + file, = @serializer_instance.method(:some_method).source_location + assert_match(%r{/lib/ams/serializer.rb\z}, file) + end + + def test_serializer_instance_raises_method_missing + exception = assert_raises(NameError) do + @serializer_instance.non_existent_method + end + assert_match(%r{undefined method `non_existent_method' for #\z}, exception.message) + end + + def test_serializer_object_raises_method_missing + exception = assert_raises(NameError) do + @serializer_instance.method(:non_existent_method) + end + assert_match(%r{undefined method `non_existent_method' for class `AMS::Serializer::ObjectDelegationTest::ParentModelSerializer'\z}, exception.message) + end end end end