mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00

fix commit miss * test/test_forwardable.rb: add tests for r53381. * lib/forwardable.rb: Convert given accessors to String. r53381 changed to accept only Symbol or String for accessors, but there are several rubygems that pass classes (e.g. Array, Hash, ...) as accessors. Prior r53381, it was accepted because Class#to_s returns its class name. After r53381 given accessors are checked with define_method, but it accepts only Symbol or String, otherwise raises TypeError. def_delegator Foo, :some_method This change is to revert unwanted incompatibility. But this behavior may change in the future. This change is to revert unexpected incompatibility. But this behavior git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@54711 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
248 lines
5.8 KiB
Ruby
248 lines
5.8 KiB
Ruby
# frozen_string_literal: false
|
|
require 'test/unit'
|
|
require 'forwardable'
|
|
|
|
class TestForwardable < Test::Unit::TestCase
|
|
RECEIVER = BasicObject.new
|
|
RETURNED1 = BasicObject.new
|
|
RETURNED2 = BasicObject.new
|
|
|
|
class << RECEIVER
|
|
def delegated1
|
|
RETURNED1
|
|
end
|
|
|
|
def delegated2
|
|
RETURNED2
|
|
end
|
|
end
|
|
|
|
def test_def_instance_delegator
|
|
%i[def_delegator def_instance_delegator].each do |m|
|
|
cls = forwardable_class do
|
|
__send__ m, :@receiver, :delegated1
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
end
|
|
end
|
|
|
|
def test_def_instance_delegator_using_args_method_as_receiver
|
|
%i[def_delegator def_instance_delegator].each do |m|
|
|
cls = forwardable_class(
|
|
receiver_name: :args,
|
|
type: :method,
|
|
visibility: :private
|
|
) do
|
|
__send__ m, :args, :delegated1
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
end
|
|
end
|
|
|
|
def test_def_instance_delegator_using_block_method_as_receiver
|
|
%i[def_delegator def_instance_delegator].each do |m|
|
|
cls = forwardable_class(
|
|
receiver_name: :block,
|
|
type: :method,
|
|
visibility: :private
|
|
) do
|
|
__send__ m, :block, :delegated1
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
end
|
|
end
|
|
|
|
def test_def_instance_delegators
|
|
%i[def_delegators def_instance_delegators].each do |m|
|
|
cls = forwardable_class do
|
|
__send__ m, :@receiver, :delegated1, :delegated2
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
assert_same RETURNED2, cls.new.delegated2
|
|
end
|
|
end
|
|
|
|
def test_def_instance_delegators_using_args_method_as_receiver
|
|
%i[def_delegators def_instance_delegators].each do |m|
|
|
cls = forwardable_class(
|
|
receiver_name: :args,
|
|
type: :method,
|
|
visibility: :private
|
|
) do
|
|
__send__ m, :args, :delegated1, :delegated2
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
assert_same RETURNED2, cls.new.delegated2
|
|
end
|
|
end
|
|
|
|
def test_def_instance_delegators_using_block_method_as_receiver
|
|
%i[def_delegators def_instance_delegators].each do |m|
|
|
cls = forwardable_class(
|
|
receiver_name: :block,
|
|
type: :method,
|
|
visibility: :private
|
|
) do
|
|
__send__ m, :block, :delegated1, :delegated2
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
assert_same RETURNED2, cls.new.delegated2
|
|
end
|
|
end
|
|
|
|
def test_instance_delegate
|
|
%i[delegate instance_delegate].each do |m|
|
|
cls = forwardable_class do
|
|
__send__ m, delegated1: :@receiver, delegated2: :@receiver
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
assert_same RETURNED2, cls.new.delegated2
|
|
|
|
cls = forwardable_class do
|
|
__send__ m, %i[delegated1 delegated2] => :@receiver
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
assert_same RETURNED2, cls.new.delegated2
|
|
end
|
|
end
|
|
|
|
def test_def_instance_delegate_using_args_method_as_receiver
|
|
%i[delegate instance_delegate].each do |m|
|
|
cls = forwardable_class(
|
|
receiver_name: :args,
|
|
type: :method,
|
|
visibility: :private
|
|
) do
|
|
__send__ m, delegated1: :args, delegated2: :args
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
assert_same RETURNED2, cls.new.delegated2
|
|
end
|
|
end
|
|
|
|
def test_def_instance_delegate_using_block_method_as_receiver
|
|
%i[delegate instance_delegate].each do |m|
|
|
cls = forwardable_class(
|
|
receiver_name: :block,
|
|
type: :method,
|
|
visibility: :private
|
|
) do
|
|
__send__ m, delegated1: :block, delegated2: :block
|
|
end
|
|
|
|
assert_same RETURNED1, cls.new.delegated1
|
|
assert_same RETURNED2, cls.new.delegated2
|
|
end
|
|
end
|
|
|
|
def test_def_single_delegator
|
|
%i[def_delegator def_single_delegator].each do |m|
|
|
cls = single_forwardable_class do
|
|
__send__ m, :@receiver, :delegated1
|
|
end
|
|
|
|
assert_same RETURNED1, cls.delegated1
|
|
end
|
|
end
|
|
|
|
def test_def_single_delegators
|
|
%i[def_delegators def_single_delegators].each do |m|
|
|
cls = single_forwardable_class do
|
|
__send__ m, :@receiver, :delegated1, :delegated2
|
|
end
|
|
|
|
assert_same RETURNED1, cls.delegated1
|
|
assert_same RETURNED2, cls.delegated2
|
|
end
|
|
end
|
|
|
|
def test_single_delegate
|
|
%i[delegate single_delegate].each do |m|
|
|
cls = single_forwardable_class do
|
|
__send__ m, delegated1: :@receiver, delegated2: :@receiver
|
|
end
|
|
|
|
assert_same RETURNED1, cls.delegated1
|
|
assert_same RETURNED2, cls.delegated2
|
|
|
|
cls = single_forwardable_class do
|
|
__send__ m, %i[delegated1 delegated2] => :@receiver
|
|
end
|
|
|
|
assert_same RETURNED1, cls.delegated1
|
|
assert_same RETURNED2, cls.delegated2
|
|
end
|
|
end
|
|
|
|
class Foo
|
|
extend Forwardable
|
|
|
|
def_delegator :bar, :baz
|
|
|
|
class Exception
|
|
end
|
|
end
|
|
|
|
def test_backtrace_adjustment
|
|
e = assert_raise(NameError) {
|
|
Foo.new.baz
|
|
}
|
|
assert_not_match(/\/forwardable\.rb/, e.backtrace[0])
|
|
end
|
|
|
|
class Foo2 < BasicObject
|
|
extend ::Forwardable
|
|
|
|
def_delegator :bar, :baz
|
|
end
|
|
|
|
def test_basicobject_subclass
|
|
bug11616 = '[ruby-core:71176] [Bug #11616]'
|
|
assert_raise_with_message(NameError, /`bar'/, bug11616) {
|
|
Foo2.new.baz
|
|
}
|
|
end
|
|
|
|
private
|
|
|
|
def forwardable_class(
|
|
receiver_name: :receiver,
|
|
type: :ivar,
|
|
visibility: :public,
|
|
&block
|
|
)
|
|
Class.new do
|
|
extend Forwardable
|
|
|
|
define_method(:initialize) do
|
|
instance_variable_set("@#{receiver_name}", RECEIVER)
|
|
end
|
|
|
|
if type == :method
|
|
attr_reader(receiver_name)
|
|
__send__(visibility, receiver_name)
|
|
end
|
|
|
|
class_exec(&block)
|
|
end
|
|
end
|
|
|
|
def single_forwardable_class(&block)
|
|
Class.new do
|
|
extend SingleForwardable
|
|
|
|
@receiver = RECEIVER
|
|
|
|
class_exec(&block)
|
|
end
|
|
end
|
|
end
|