mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
ffd0820ab3
This removes the related tests, and puts the related specs behind version guards. This affects all code in lib, including some libraries that may want to support older versions of Ruby.
966 lines
25 KiB
Ruby
966 lines
25 KiB
Ruby
# -*- coding: us-ascii -*-
|
|
# frozen_string_literal: false
|
|
require 'test/unit'
|
|
|
|
class TestObject < Test::Unit::TestCase
|
|
def setup
|
|
@verbose = $VERBOSE
|
|
$VERBOSE = nil
|
|
end
|
|
|
|
def teardown
|
|
$VERBOSE = @verbose
|
|
end
|
|
|
|
def test_itself
|
|
feature6373 = '[ruby-core:44704] [Feature #6373]'
|
|
object = Object.new
|
|
assert_same(object, object.itself, feature6373)
|
|
end
|
|
|
|
def test_yield_self
|
|
feature = '[ruby-core:46320] [Feature #6721]'
|
|
object = Object.new
|
|
assert_same(self, object.yield_self {self}, feature)
|
|
assert_same(object, object.yield_self {|x| break x}, feature)
|
|
enum = object.yield_self
|
|
assert_instance_of(Enumerator, enum)
|
|
assert_equal(1, enum.size)
|
|
end
|
|
|
|
def test_dup
|
|
assert_equal 1, 1.dup
|
|
assert_equal true, true.dup
|
|
assert_equal nil, nil.dup
|
|
assert_equal false, false.dup
|
|
x = :x; assert_equal x, x.dup
|
|
x = "bug13145".intern; assert_equal x, x.dup
|
|
x = 1 << 64; assert_equal x, x.dup
|
|
x = 1.72723e-77; assert_equal x, x.dup
|
|
|
|
assert_raise(TypeError) do
|
|
Object.new.instance_eval { initialize_copy(1) }
|
|
end
|
|
end
|
|
|
|
def test_clone
|
|
a = Object.new
|
|
def a.b; 2 end
|
|
|
|
a.freeze
|
|
c = a.clone
|
|
assert_equal(true, c.frozen?)
|
|
assert_equal(2, c.b)
|
|
|
|
assert_raise(ArgumentError) {a.clone(freeze: [])}
|
|
d = a.clone(freeze: false)
|
|
def d.e; 3; end
|
|
assert_equal(false, d.frozen?)
|
|
assert_equal(2, d.b)
|
|
assert_equal(3, d.e)
|
|
|
|
assert_equal 1, 1.clone
|
|
assert_equal true, true.clone
|
|
assert_equal nil, nil.clone
|
|
assert_equal false, false.clone
|
|
x = :x; assert_equal x, x.dup
|
|
x = "bug13145".intern; assert_equal x, x.dup
|
|
x = 1 << 64; assert_equal x, x.clone
|
|
x = 1.72723e-77; assert_equal x, x.clone
|
|
assert_raise(ArgumentError) {1.clone(freeze: false)}
|
|
assert_raise(ArgumentError) {true.clone(freeze: false)}
|
|
assert_raise(ArgumentError) {nil.clone(freeze: false)}
|
|
assert_raise(ArgumentError) {false.clone(freeze: false)}
|
|
x = EnvUtil.labeled_class("\u{1f4a9}").new
|
|
assert_raise_with_message(ArgumentError, /\u{1f4a9}/) do
|
|
Object.new.clone(freeze: x)
|
|
end
|
|
end
|
|
|
|
def test_init_dupclone
|
|
cls = Class.new do
|
|
def initialize_clone(orig); throw :initialize_clone; end
|
|
def initialize_dup(orig); throw :initialize_dup; end
|
|
end
|
|
|
|
obj = cls.new
|
|
assert_throw(:initialize_clone) {obj.clone}
|
|
assert_throw(:initialize_dup) {obj.dup}
|
|
end
|
|
|
|
def test_instance_of
|
|
assert_raise(TypeError) { 1.instance_of?(1) }
|
|
end
|
|
|
|
def test_kind_of
|
|
assert_raise(TypeError) { 1.kind_of?(1) }
|
|
end
|
|
|
|
def test_freeze_immediate
|
|
assert_equal(true, 1.frozen?)
|
|
1.freeze
|
|
assert_equal(true, 1.frozen?)
|
|
assert_equal(true, 2.frozen?)
|
|
assert_equal(true, true.frozen?)
|
|
assert_equal(true, false.frozen?)
|
|
assert_equal(true, nil.frozen?)
|
|
end
|
|
|
|
def test_frozen_error_message
|
|
name = "C\u{30c6 30b9 30c8}"
|
|
klass = EnvUtil.labeled_class(name) {
|
|
attr_accessor :foo
|
|
}
|
|
obj = klass.new.freeze
|
|
assert_raise_with_message(FrozenError, /#{name}/) {
|
|
obj.foo = 1
|
|
}
|
|
end
|
|
|
|
def test_nil_to_f
|
|
assert_equal(0.0, nil.to_f)
|
|
end
|
|
|
|
def test_nil_to_s
|
|
str = nil.to_s
|
|
assert_equal("", str)
|
|
assert_predicate(str, :frozen?)
|
|
assert_same(str, nil.to_s)
|
|
end
|
|
|
|
def test_true_to_s
|
|
str = true.to_s
|
|
assert_equal("true", str)
|
|
assert_predicate(str, :frozen?)
|
|
assert_same(str, true.to_s)
|
|
end
|
|
|
|
def test_false_to_s
|
|
str = false.to_s
|
|
assert_equal("false", str)
|
|
assert_predicate(str, :frozen?)
|
|
assert_same(str, false.to_s)
|
|
end
|
|
|
|
def test_not
|
|
assert_equal(false, Object.new.send(:!))
|
|
assert_equal(true, nil.send(:!))
|
|
end
|
|
|
|
def test_true_and
|
|
assert_equal(true, true & true)
|
|
assert_equal(true, true & 1)
|
|
assert_equal(false, true & false)
|
|
assert_equal(false, true & nil)
|
|
end
|
|
|
|
def test_true_or
|
|
assert_equal(true, true | true)
|
|
assert_equal(true, true | 1)
|
|
assert_equal(true, true | false)
|
|
assert_equal(true, true | nil)
|
|
end
|
|
|
|
def test_true_xor
|
|
assert_equal(false, true ^ true)
|
|
assert_equal(false, true ^ 1)
|
|
assert_equal(true, true ^ false)
|
|
assert_equal(true, true ^ nil)
|
|
end
|
|
|
|
def test_false_and
|
|
assert_equal(false, false & true)
|
|
assert_equal(false, false & 1)
|
|
assert_equal(false, false & false)
|
|
assert_equal(false, false & nil)
|
|
end
|
|
|
|
def test_false_or
|
|
assert_equal(true, false | true)
|
|
assert_equal(true, false | 1)
|
|
assert_equal(false, false | false)
|
|
assert_equal(false, false | nil)
|
|
end
|
|
|
|
def test_false_xor
|
|
assert_equal(true, false ^ true)
|
|
assert_equal(true, false ^ 1)
|
|
assert_equal(false, false ^ false)
|
|
assert_equal(false, false ^ nil)
|
|
end
|
|
|
|
def test_methods
|
|
o = Object.new
|
|
a1 = o.methods
|
|
a2 = o.methods(false)
|
|
|
|
def o.foo; end
|
|
|
|
assert_equal([:foo], o.methods(true) - a1)
|
|
assert_equal([:foo], o.methods(false) - a2)
|
|
end
|
|
|
|
def test_methods2
|
|
c0 = Class.new
|
|
c1 = Class.new(c0)
|
|
c1.module_eval do
|
|
public ; def foo; end
|
|
protected; def bar; end
|
|
private ; def baz; end
|
|
end
|
|
c2 = Class.new(c1)
|
|
c2.module_eval do
|
|
public ; def foo2; end
|
|
protected; def bar2; end
|
|
private ; def baz2; end
|
|
end
|
|
|
|
o0 = c0.new
|
|
o2 = c2.new
|
|
|
|
assert_equal([:baz, :baz2], (o2.private_methods - o0.private_methods).sort)
|
|
assert_equal([:baz2], (o2.private_methods(false) - o0.private_methods(false)).sort)
|
|
|
|
assert_equal([:bar, :bar2], (o2.protected_methods - o0.protected_methods).sort)
|
|
assert_equal([:bar2], (o2.protected_methods(false) - o0.protected_methods(false)).sort)
|
|
|
|
assert_equal([:foo, :foo2], (o2.public_methods - o0.public_methods).sort)
|
|
assert_equal([:foo2], (o2.public_methods(false) - o0.public_methods(false)).sort)
|
|
end
|
|
|
|
def test_methods_prepend
|
|
bug8044 = '[ruby-core:53207] [Bug #8044]'
|
|
o = Object.new
|
|
def o.foo; end
|
|
assert_equal([:foo], o.methods(false))
|
|
class << o; prepend Module.new; end
|
|
assert_equal([:foo], o.methods(false), bug8044)
|
|
end
|
|
|
|
def test_methods_prepend_singleton
|
|
c = Class.new(Module) {private def foo; end}
|
|
k = c.new
|
|
k.singleton_class
|
|
c.module_eval {prepend(Module.new)}
|
|
assert_equal([:foo], k.private_methods(false))
|
|
end
|
|
|
|
def test_instance_variable_get
|
|
o = Object.new
|
|
o.instance_eval { @foo = :foo }
|
|
assert_equal(:foo, o.instance_variable_get(:@foo))
|
|
assert_equal(nil, o.instance_variable_get(:@bar))
|
|
assert_raise(NameError) { o.instance_variable_get('@') }
|
|
assert_raise(NameError) { o.instance_variable_get(:'@') }
|
|
assert_raise(NameError) { o.instance_variable_get(:foo) }
|
|
assert_raise(NameError) { o.instance_variable_get("bar") }
|
|
assert_raise(TypeError) { o.instance_variable_get(1) }
|
|
|
|
n = Object.new
|
|
def n.to_str; @count = defined?(@count) ? @count + 1 : 1; "@foo"; end
|
|
def n.count; @count; end
|
|
assert_equal(:foo, o.instance_variable_get(n))
|
|
assert_equal(1, n.count)
|
|
end
|
|
|
|
def test_instance_variable_set
|
|
o = Object.new
|
|
o.instance_variable_set(:@foo, :foo)
|
|
assert_equal(:foo, o.instance_eval { @foo })
|
|
assert_raise(NameError) { o.instance_variable_set(:'@', 1) }
|
|
assert_raise(NameError) { o.instance_variable_set('@', 1) }
|
|
assert_raise(NameError) { o.instance_variable_set(:foo, 1) }
|
|
assert_raise(NameError) { o.instance_variable_set("bar", 1) }
|
|
assert_raise(TypeError) { o.instance_variable_set(1, 1) }
|
|
|
|
n = Object.new
|
|
def n.to_str; @count = defined?(@count) ? @count + 1 : 1; "@foo"; end
|
|
def n.count; @count; end
|
|
o.instance_variable_set(n, :bar)
|
|
assert_equal(:bar, o.instance_eval { @foo })
|
|
assert_equal(1, n.count)
|
|
end
|
|
|
|
def test_instance_variable_defined
|
|
o = Object.new
|
|
o.instance_eval { @foo = :foo }
|
|
assert_equal(true, o.instance_variable_defined?(:@foo))
|
|
assert_equal(false, o.instance_variable_defined?(:@bar))
|
|
assert_raise(NameError) { o.instance_variable_defined?(:'@') }
|
|
assert_raise(NameError) { o.instance_variable_defined?('@') }
|
|
assert_raise(NameError) { o.instance_variable_defined?(:foo) }
|
|
assert_raise(NameError) { o.instance_variable_defined?("bar") }
|
|
assert_raise(TypeError) { o.instance_variable_defined?(1) }
|
|
|
|
n = Object.new
|
|
def n.to_str; @count = defined?(@count) ? @count + 1 : 1; "@foo"; end
|
|
def n.count; @count; end
|
|
assert_equal(true, o.instance_variable_defined?(n))
|
|
assert_equal(1, n.count)
|
|
end
|
|
|
|
def test_remove_instance_variable
|
|
{ 'T_OBJECT' => Object.new,
|
|
'T_CLASS,T_MODULE' => Class.new(Object),
|
|
'generic ivar' => '',
|
|
}.each do |desc, o|
|
|
e = assert_raise(NameError, "#{desc} iv removal raises before set") do
|
|
o.remove_instance_variable(:@foo)
|
|
end
|
|
assert_equal([o, :@foo], [e.receiver, e.name])
|
|
o.instance_eval { @foo = :foo }
|
|
assert_equal(:foo, o.remove_instance_variable(:@foo),
|
|
"#{desc} iv removal returns original value")
|
|
assert_not_send([o, :instance_variable_defined?, :@foo],
|
|
"#{desc} iv removed successfully")
|
|
e = assert_raise(NameError, "#{desc} iv removal raises after removal") do
|
|
o.remove_instance_variable(:@foo)
|
|
end
|
|
assert_equal([o, :@foo], [e.receiver, e.name])
|
|
end
|
|
end
|
|
|
|
def test_convert_string
|
|
o = Object.new
|
|
def o.to_s; 1; end
|
|
assert_raise(TypeError) { String(o) }
|
|
def o.to_s; "o"; end
|
|
assert_equal("o", String(o))
|
|
def o.to_str; "O"; end
|
|
assert_equal("O", String(o))
|
|
def o.respond_to?(*) false; end
|
|
assert_raise(TypeError) { String(o) }
|
|
end
|
|
|
|
def test_convert_array
|
|
o = Object.new
|
|
def o.to_a; 1; end
|
|
assert_raise(TypeError) { Array(o) }
|
|
def o.to_a; [1]; end
|
|
assert_equal([1], Array(o))
|
|
def o.to_ary; [2]; end
|
|
assert_equal([2], Array(o))
|
|
def o.respond_to?(*) false; end
|
|
assert_equal([o], Array(o))
|
|
end
|
|
|
|
def test_convert_hash
|
|
assert_equal({}, Hash(nil))
|
|
assert_equal({}, Hash([]))
|
|
assert_equal({key: :value}, Hash(key: :value))
|
|
assert_raise(TypeError) { Hash([1,2]) }
|
|
assert_raise(TypeError) { Hash(Object.new) }
|
|
o = Object.new
|
|
def o.to_hash; {a: 1, b: 2}; end
|
|
assert_equal({a: 1, b: 2}, Hash(o))
|
|
def o.to_hash; 9; end
|
|
assert_raise(TypeError) { Hash(o) }
|
|
end
|
|
|
|
def test_to_integer
|
|
o = Object.new
|
|
def o.to_i; nil; end
|
|
assert_raise(TypeError) { Integer(o) }
|
|
def o.to_i; 42; end
|
|
assert_equal(42, Integer(o))
|
|
def o.respond_to?(*) false; end
|
|
assert_raise(TypeError) { Integer(o) }
|
|
end
|
|
|
|
class MyInteger
|
|
def initialize(n); @num = n; end
|
|
def to_int; @num; end
|
|
def <=>(n); @num <=> n.to_int; end
|
|
def <=(n); @num <= n.to_int; end
|
|
def +(n); MyInteger.new(@num + n.to_int); end
|
|
end
|
|
|
|
def test_check_to_integer
|
|
o1 = MyInteger.new(1)
|
|
o9 = MyInteger.new(9)
|
|
n = 0
|
|
Range.new(o1, o9).step(2) {|x| n += x.to_int }
|
|
assert_equal(1+3+5+7+9, n)
|
|
end
|
|
|
|
def test_redefine_method_under_verbose
|
|
assert_in_out_err([], <<-INPUT, %w(2), /warning: method redefined; discarding old foo$/)
|
|
$VERBOSE = true
|
|
o = Object.new
|
|
def o.foo; 1; end
|
|
def o.foo; 2; end
|
|
p o.foo
|
|
INPUT
|
|
end
|
|
|
|
def test_redefine_method_which_may_case_serious_problem
|
|
assert_in_out_err([], <<-INPUT, [], %r"warning: redefining `object_id' may cause serious problems$")
|
|
$VERBOSE = false
|
|
def (Object.new).object_id; end
|
|
INPUT
|
|
|
|
assert_in_out_err([], <<-INPUT, [], %r"warning: redefining `__send__' may cause serious problems$")
|
|
$VERBOSE = false
|
|
def (Object.new).__send__; end
|
|
INPUT
|
|
|
|
bug10421 = '[ruby-dev:48691] [Bug #10421]'
|
|
assert_in_out_err([], <<-INPUT, ["1"], [], bug10421)
|
|
$VERBOSE = false
|
|
class C < BasicObject
|
|
def object_id; 1; end
|
|
end
|
|
puts C.new.object_id
|
|
INPUT
|
|
end
|
|
|
|
def test_remove_method
|
|
c = Class.new
|
|
c.freeze
|
|
assert_raise(FrozenError) do
|
|
c.instance_eval { remove_method(:foo) }
|
|
end
|
|
|
|
c = Class.new do
|
|
def meth1; "meth" end
|
|
end
|
|
d = Class.new(c) do
|
|
alias meth2 meth1
|
|
end
|
|
o1 = c.new
|
|
assert_respond_to(o1, :meth1)
|
|
assert_equal("meth", o1.meth1)
|
|
o2 = d.new
|
|
assert_respond_to(o2, :meth1)
|
|
assert_equal("meth", o2.meth1)
|
|
assert_respond_to(o2, :meth2)
|
|
assert_equal("meth", o2.meth2)
|
|
d.class_eval do
|
|
remove_method :meth2
|
|
end
|
|
bug2202 = '[ruby-core:26074]'
|
|
assert_raise(NoMethodError, bug2202) {o2.meth2}
|
|
|
|
%w(object_id __send__ initialize).each do |m|
|
|
assert_in_out_err([], <<-INPUT, %w(:ok), %r"warning: removing `#{m}' may cause serious problems$")
|
|
$VERBOSE = false
|
|
begin
|
|
Class.new.instance_eval { remove_method(:#{m}) }
|
|
rescue NameError
|
|
p :ok
|
|
end
|
|
INPUT
|
|
end
|
|
|
|
m = "\u{30e1 30bd 30c3 30c9}"
|
|
c = Class.new
|
|
assert_raise_with_message(NameError, /#{m}/) do
|
|
c.class_eval {remove_method m}
|
|
end
|
|
c = Class.new {
|
|
define_method(m) {}
|
|
remove_method(m)
|
|
}
|
|
assert_raise_with_message(NameError, /#{m}/) do
|
|
c.class_eval {remove_method m}
|
|
end
|
|
end
|
|
|
|
def test_method_missing
|
|
assert_raise(ArgumentError) do
|
|
1.instance_eval { method_missing }
|
|
end
|
|
|
|
c = Class.new
|
|
c.class_eval do
|
|
protected
|
|
def foo; end
|
|
end
|
|
assert_raise(NoMethodError) do
|
|
c.new.foo
|
|
end
|
|
|
|
assert_raise(NoMethodError) do
|
|
1.instance_eval { method_missing(:method_missing) }
|
|
end
|
|
|
|
c.class_eval do
|
|
undef_method(:method_missing)
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
c.new.method_missing
|
|
end
|
|
|
|
bug2494 = '[ruby-core:27219]'
|
|
c = Class.new do
|
|
def method_missing(meth, *args)
|
|
super
|
|
end
|
|
end
|
|
b = c.new
|
|
foo rescue nil
|
|
assert_nothing_raised(bug2494) {[b].flatten}
|
|
end
|
|
|
|
def test_respond_to_missing_string
|
|
c = Class.new do
|
|
def respond_to_missing?(id, priv)
|
|
!(id !~ /\Agadzoks\d+\z/) ^ priv
|
|
end
|
|
end
|
|
foo = c.new
|
|
assert_equal(false, foo.respond_to?("gadzooks16"))
|
|
assert_equal(true, foo.respond_to?("gadzooks17", true))
|
|
assert_equal(true, foo.respond_to?("gadzoks16"))
|
|
assert_equal(false, foo.respond_to?("gadzoks17", true))
|
|
end
|
|
|
|
def test_respond_to_missing
|
|
c = Class.new do
|
|
def respond_to_missing?(id, priv)
|
|
if id == :foobar
|
|
true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
def method_missing(id, *args)
|
|
if id == :foobar
|
|
return [:foo, *args]
|
|
else
|
|
super
|
|
end
|
|
end
|
|
end
|
|
|
|
foo = c.new
|
|
assert_equal([:foo], foo.foobar);
|
|
assert_equal([:foo, 1], foo.foobar(1));
|
|
assert_equal([:foo, 1, 2, 3, 4, 5], foo.foobar(1, 2, 3, 4, 5));
|
|
assert_respond_to(foo, :foobar)
|
|
assert_not_respond_to(foo, :foobarbaz)
|
|
assert_raise(NoMethodError) do
|
|
foo.foobarbaz
|
|
end
|
|
|
|
foobar = foo.method(:foobar)
|
|
assert_equal(-1, foobar.arity);
|
|
assert_equal([:foo], foobar.call);
|
|
assert_equal([:foo, 1], foobar.call(1));
|
|
assert_equal([:foo, 1, 2, 3, 4, 5], foobar.call(1, 2, 3, 4, 5));
|
|
assert_equal(foobar, foo.method(:foobar))
|
|
assert_not_equal(foobar, c.new.method(:foobar))
|
|
|
|
c = Class.new(c)
|
|
assert_equal(false, c.method_defined?(:foobar))
|
|
assert_raise(NameError, '[ruby-core:25748]') do
|
|
c.instance_method(:foobar)
|
|
end
|
|
|
|
m = Module.new
|
|
assert_equal(false, m.method_defined?(:foobar))
|
|
assert_raise(NameError, '[ruby-core:25748]') do
|
|
m.instance_method(:foobar)
|
|
end
|
|
end
|
|
|
|
def test_implicit_respond_to
|
|
bug5158 = '[ruby-core:38799]'
|
|
|
|
p = Object.new
|
|
|
|
called = []
|
|
p.singleton_class.class_eval do
|
|
define_method(:to_ary) do
|
|
called << [:to_ary, bug5158]
|
|
end
|
|
end
|
|
[[p]].flatten
|
|
assert_equal([[:to_ary, bug5158]], called, bug5158)
|
|
|
|
called = []
|
|
p.singleton_class.class_eval do
|
|
define_method(:respond_to?) do |*a|
|
|
called << [:respond_to?, *a]
|
|
false
|
|
end
|
|
end
|
|
[[p]].flatten
|
|
assert_equal([[:respond_to?, :to_ary, true]], called, bug5158)
|
|
end
|
|
|
|
def test_implicit_respond_to_arity_1
|
|
p = Object.new
|
|
|
|
called = []
|
|
p.singleton_class.class_eval do
|
|
define_method(:respond_to?) do |a|
|
|
called << [:respond_to?, a]
|
|
false
|
|
end
|
|
end
|
|
[[p]].flatten
|
|
assert_equal([[:respond_to?, :to_ary]], called, '[bug:6000]')
|
|
end
|
|
|
|
def test_implicit_respond_to_arity_3
|
|
p = Object.new
|
|
|
|
called = []
|
|
p.singleton_class.class_eval do
|
|
define_method(:respond_to?) do |a, b, c|
|
|
called << [:respond_to?, a, b, c]
|
|
false
|
|
end
|
|
end
|
|
|
|
msg = 'respond_to? must accept 1 or 2 arguments (requires 3)'
|
|
assert_raise_with_message(ArgumentError, msg, '[bug:6000]') do
|
|
[[p]].flatten
|
|
end
|
|
end
|
|
|
|
def test_method_missing_passed_block
|
|
bug5731 = '[ruby-dev:44961]'
|
|
|
|
c = Class.new do
|
|
def method_missing(meth, *args) yield(meth, *args) end
|
|
end
|
|
a = c.new
|
|
result = nil
|
|
assert_nothing_raised(LocalJumpError, bug5731) do
|
|
a.foo {|x| result = x}
|
|
end
|
|
assert_equal(:foo, result, bug5731)
|
|
result = nil
|
|
e = a.enum_for(:foo)
|
|
assert_nothing_raised(LocalJumpError, bug5731) do
|
|
e.each {|x| result = x}
|
|
end
|
|
assert_equal(:foo, result, bug5731)
|
|
|
|
c = Class.new do
|
|
def respond_to_missing?(id, priv)
|
|
true
|
|
end
|
|
def method_missing(id, *args, &block)
|
|
return block.call(:foo, *args)
|
|
end
|
|
end
|
|
foo = c.new
|
|
|
|
result = nil
|
|
assert_nothing_raised(LocalJumpError, bug5731) do
|
|
foo.foobar {|x| result = x}
|
|
end
|
|
assert_equal(:foo, result, bug5731)
|
|
result = nil
|
|
assert_nothing_raised(LocalJumpError, bug5731) do
|
|
foo.enum_for(:foobar).each {|x| result = x}
|
|
end
|
|
assert_equal(:foo, result, bug5731)
|
|
|
|
result = nil
|
|
foobar = foo.method(:foobar)
|
|
foobar.call {|x| result = x}
|
|
assert_equal(:foo, result, bug5731)
|
|
|
|
result = nil
|
|
foobar = foo.method(:foobar)
|
|
foobar.enum_for(:call).each {|x| result = x}
|
|
assert_equal(:foo, result, bug5731)
|
|
end
|
|
|
|
def test_send_with_no_arguments
|
|
assert_raise(ArgumentError) { 1.send }
|
|
end
|
|
|
|
def test_send_with_block
|
|
x = :ng
|
|
1.send(:times) { x = :ok }
|
|
assert_equal(:ok, x)
|
|
|
|
x = :ok
|
|
o = Object.new
|
|
def o.inspect
|
|
yield if block_given?
|
|
super
|
|
end
|
|
begin
|
|
nil.public_send(o) { x = :ng }
|
|
rescue TypeError
|
|
end
|
|
assert_equal(:ok, x)
|
|
end
|
|
|
|
def test_public_send
|
|
c = Class.new do
|
|
def pub
|
|
:ok
|
|
end
|
|
|
|
def invoke(m)
|
|
public_send(m)
|
|
end
|
|
|
|
protected
|
|
def prot
|
|
:ng
|
|
end
|
|
|
|
private
|
|
def priv
|
|
:ng
|
|
end
|
|
end.new
|
|
assert_equal(:ok, c.public_send(:pub))
|
|
assert_raise(NoMethodError) {c.public_send(:priv)}
|
|
assert_raise(NoMethodError) {c.public_send(:prot)}
|
|
assert_raise(NoMethodError) {c.invoke(:priv)}
|
|
bug7499 = '[ruby-core:50489]'
|
|
assert_raise(NoMethodError, bug7499) {c.invoke(:prot)}
|
|
end
|
|
|
|
def test_no_superclass_method
|
|
bug2312 = '[ruby-dev:39581]'
|
|
|
|
o = Object.new
|
|
e = assert_raise(NoMethodError) {
|
|
o.method(:__send__).call(:never_defined_test_no_superclass_method)
|
|
}
|
|
m1 = e.message
|
|
assert_no_match(/no superclass method/, m1, bug2312)
|
|
e = assert_raise(NoMethodError) {
|
|
o.method(:__send__).call(:never_defined_test_no_superclass_method)
|
|
}
|
|
assert_equal(m1, e.message, bug2312)
|
|
e = assert_raise(NoMethodError) {
|
|
o.never_defined_test_no_superclass_method
|
|
}
|
|
assert_equal(m1, e.message, bug2312)
|
|
end
|
|
|
|
def test_superclass_method
|
|
bug2312 = '[ruby-dev:39581]'
|
|
assert_in_out_err(["-e", "module Enumerable;undef min;end; (1..2).min{}"],
|
|
"", [], /no superclass method/, bug2312)
|
|
end
|
|
|
|
def test_specific_eval_with_wrong_arguments
|
|
assert_raise(ArgumentError) do
|
|
1.instance_eval("foo") { foo }
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
1.instance_eval
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
1.instance_eval("", 1, 1, 1)
|
|
end
|
|
end
|
|
|
|
class InstanceExec
|
|
INSTANCE_EXEC = 123
|
|
end
|
|
|
|
def test_instance_exec
|
|
x = 1.instance_exec(42) {|a| self + a }
|
|
assert_equal(43, x)
|
|
|
|
x = "foo".instance_exec("bar") {|a| self + a }
|
|
assert_equal("foobar", x)
|
|
|
|
assert_raise(NameError) do
|
|
InstanceExec.new.instance_exec { INSTANCE_EXEC }
|
|
end
|
|
end
|
|
|
|
def test_extend
|
|
assert_raise(ArgumentError) do
|
|
1.extend
|
|
end
|
|
end
|
|
|
|
def test_to_s
|
|
x = eval(<<-EOS)
|
|
class ToS\u{3042}
|
|
new.to_s
|
|
end
|
|
EOS
|
|
assert_match(/\bToS\u{3042}:/, x)
|
|
|
|
name = "X".freeze
|
|
x = Object.new
|
|
class<<x;self;end.class_eval {define_method(:to_s) {name}}
|
|
assert_same(name, x.to_s)
|
|
assert_equal("X", [x].join(""))
|
|
end
|
|
|
|
def test_inspect
|
|
x = Object.new
|
|
assert_match(/\A#<Object:0x\h+>\z/, x.inspect)
|
|
|
|
x.instance_variable_set(:@ivar, :value)
|
|
assert_match(/\A#<Object:0x\h+ @ivar=:value>\z/, x.inspect)
|
|
|
|
x = Object.new
|
|
x.instance_variable_set(:@recur, x)
|
|
assert_match(/\A#<Object:0x\h+ @recur=#<Object:0x\h+ \.\.\.>>\z/, x.inspect)
|
|
|
|
x = Object.new
|
|
x.instance_variable_set(:@foo, "value")
|
|
x.instance_variable_set(:@bar, 42)
|
|
assert_match(/\A#<Object:0x\h+ (?:@foo="value", @bar=42|@bar=42, @foo="value")>\z/, x.inspect)
|
|
|
|
# #inspect does not call #to_s anymore
|
|
feature6130 = '[ruby-core:43238]'
|
|
x = Object.new
|
|
def x.to_s
|
|
"to_s"
|
|
end
|
|
assert_match(/\A#<Object:0x\h+>\z/, x.inspect, feature6130)
|
|
|
|
x = eval(<<-EOS)
|
|
class Inspect\u{3042}
|
|
new.inspect
|
|
end
|
|
EOS
|
|
assert_match(/\bInspect\u{3042}:/, x)
|
|
|
|
x = eval(<<-EOS)
|
|
class Inspect\u{3042}
|
|
def initialize
|
|
@\u{3044} = 42
|
|
end
|
|
new
|
|
end
|
|
EOS
|
|
assert_match(/\bInspect\u{3042}:.* @\u{3044}=42\b/, x.inspect)
|
|
x.instance_variable_set("@\u{3046}".encode(Encoding::EUC_JP), 6)
|
|
assert_match(/@\u{3046}=6\b/, x.inspect)
|
|
end
|
|
|
|
def test_singleton_methods
|
|
assert_equal([], Object.new.singleton_methods)
|
|
assert_equal([], Object.new.singleton_methods(false))
|
|
c = Class.new
|
|
def c.foo; end
|
|
assert_equal([:foo], c.singleton_methods - [:yaml_tag])
|
|
assert_equal([:foo], c.singleton_methods(false))
|
|
assert_equal([], c.singleton_class.singleton_methods(false))
|
|
c.singleton_class.singleton_class
|
|
assert_equal([], c.singleton_class.singleton_methods(false))
|
|
|
|
o = c.new.singleton_class
|
|
assert_equal([:foo], o.singleton_methods - [:yaml_tag])
|
|
assert_equal([], o.singleton_methods(false))
|
|
o.singleton_class
|
|
assert_equal([:foo], o.singleton_methods - [:yaml_tag])
|
|
assert_equal([], o.singleton_methods(false))
|
|
|
|
c.extend(Module.new{def bar; end})
|
|
assert_equal([:bar, :foo], c.singleton_methods.sort - [:yaml_tag])
|
|
assert_equal([:foo], c.singleton_methods(false))
|
|
end
|
|
|
|
def test_singleton_class
|
|
x = Object.new
|
|
xs = class << x; self; end
|
|
assert_equal(xs, x.singleton_class)
|
|
|
|
y = Object.new
|
|
ys = y.singleton_class
|
|
assert_equal(class << y; self; end, ys)
|
|
|
|
assert_equal(NilClass, nil.singleton_class)
|
|
assert_equal(TrueClass, true.singleton_class)
|
|
assert_equal(FalseClass, false.singleton_class)
|
|
|
|
assert_raise(TypeError) do
|
|
123.singleton_class
|
|
end
|
|
assert_raise(TypeError) do
|
|
:foo.singleton_class
|
|
end
|
|
end
|
|
|
|
def test_redef_method_missing
|
|
bug5473 = '[ruby-core:40287]'
|
|
['ArgumentError.new("bug5473")', 'ArgumentError, "bug5473"', '"bug5473"'].each do |code|
|
|
exc = code[/\A[A-Z]\w+/] || 'RuntimeError'
|
|
assert_separately([], <<-SRC)
|
|
$VERBOSE = nil
|
|
class ::Object
|
|
def method_missing(m, *a, &b)
|
|
raise #{code}
|
|
end
|
|
end
|
|
|
|
assert_raise_with_message(#{exc}, "bug5473", #{bug5473.dump}) {1.foo}
|
|
SRC
|
|
end
|
|
end
|
|
|
|
def assert_not_initialize_copy
|
|
a = yield
|
|
b = yield
|
|
assert_nothing_raised("copy") {a.instance_eval {initialize_copy(b)}}
|
|
c = a.dup.freeze
|
|
assert_raise(FrozenError, "frozen") {c.instance_eval {initialize_copy(b)}}
|
|
d = a.dup
|
|
[a, b, c, d]
|
|
end
|
|
|
|
def test_bad_initialize_copy
|
|
assert_not_initialize_copy {Object.new}
|
|
assert_not_initialize_copy {[].to_enum}
|
|
assert_not_initialize_copy {Enumerator::Generator.new {}}
|
|
assert_not_initialize_copy {Enumerator::Yielder.new {}}
|
|
assert_not_initialize_copy {File.stat(__FILE__)}
|
|
assert_not_initialize_copy {open(__FILE__)}.each(&:close)
|
|
assert_not_initialize_copy {ARGF.class.new}
|
|
assert_not_initialize_copy {Random.new}
|
|
assert_not_initialize_copy {//}
|
|
assert_not_initialize_copy {/.*/.match("foo")}
|
|
st = Struct.new(:foo)
|
|
assert_not_initialize_copy {st.new}
|
|
end
|
|
|
|
def test_type_error_message
|
|
_issue = "Bug #7539"
|
|
assert_raise_with_message(TypeError, "can't convert Array into Integer") {Integer([42])}
|
|
assert_raise_with_message(TypeError, 'no implicit conversion of Array into Integer') {[].first([42])}
|
|
assert_raise_with_message(TypeError, "can't convert Array into Rational") {Rational([42])}
|
|
end
|
|
|
|
def test_copied_ivar_memory_leak
|
|
bug10191 = '[ruby-core:64700] [Bug #10191]'
|
|
assert_no_memory_leak([], <<-"end;", <<-"end;", bug10191, timeout: 60, limit: 1.8)
|
|
def (a = Object.new).set; @v = nil; end
|
|
num = 500_000
|
|
end;
|
|
num.times {a.clone.set}
|
|
end;
|
|
end
|
|
|
|
def test_clone_object_should_not_be_old
|
|
assert_normal_exit <<-EOS, '[Bug #13775]'
|
|
b = proc { }
|
|
10.times do |i|
|
|
b.clone
|
|
GC.start
|
|
end
|
|
EOS
|
|
end
|
|
|
|
def test_matcher
|
|
assert_warning(/deprecated Object#=~ is called on Object/) do
|
|
assert_equal(Object.new =~ 42, nil)
|
|
end
|
|
assert_warning(/deprecated Object#=~ is called on Array/) do
|
|
assert_equal([] =~ 42, nil)
|
|
end
|
|
end
|
|
end
|