diff options
Diffstat (limited to 'test/ruby/test_object.rb')
| -rw-r--r-- | test/ruby/test_object.rb | 595 |
1 files changed, 390 insertions, 205 deletions
diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb index a9d2dc7ed2..f4dfe2251b 100644 --- a/test/ruby/test_object.rb +++ b/test/ruby/test_object.rb @@ -1,27 +1,117 @@ # -*- coding: us-ascii -*- +# frozen_string_literal: false require 'test/unit' -require_relative 'envutil' 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_raise(TypeError) { 1.dup } - assert_raise(TypeError) { true.dup } - assert_raise(TypeError) { nil.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 + + c = a.clone + assert_equal(false, c.frozen?) + assert_equal(false, a.frozen?) + assert_equal(2, c.b) + + c = a.clone(freeze: true) + assert_equal(true, c.frozen?) + assert_equal(false, a.frozen?) + assert_equal(2, c.b) + + a.freeze + c = a.clone + assert_equal(true, c.frozen?) + assert_equal(true, a.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(true, a.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 + + c = Class.new do + attr_reader :f + end + o = c.new + def o.initialize_clone(_, freeze: true) + @f = freeze + super + end + clone = o.clone + assert_kind_of c, clone + assert_equal true, clone.f + clone = o.clone(freeze: false) + assert_kind_of c, clone + assert_equal false, clone.f + + class << o + remove_method(:initialize_clone) + end + def o.initialize_clone(_) + super + end + assert_kind_of c, o.clone + assert_raise(ArgumentError) { o.clone(freeze: false) } + end + def test_init_dupclone cls = Class.new do def initialize_clone(orig); throw :initialize_clone; end @@ -29,8 +119,8 @@ class TestObject < Test::Unit::TestCase end obj = cls.new - assert_throws(:initialize_clone) {obj.clone} - assert_throws(:initialize_dup) {obj.dup} + assert_throw(:initialize_clone) {obj.clone} + assert_throw(:initialize_dup) {obj.dup} end def test_instance_of @@ -41,38 +131,52 @@ class TestObject < Test::Unit::TestCase assert_raise(TypeError) { 1.kind_of?(1) } end - def test_taint_frozen_obj - o = Object.new - o.freeze - assert_raise(RuntimeError) { o.taint } - - o = Object.new - o.taint - o.freeze - assert_raise(RuntimeError) { o.untaint } - end - - def test_freeze_under_safe_4 - o = Object.new - assert_raise(SecurityError) do - Thread.new do - $SAFE = 4 - o.freeze - end.join - end - 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(:!)) @@ -159,6 +263,29 @@ class TestObject < Test::Unit::TestCase 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 + + class ToStrCounter + def initialize(str = "@foo") @str = str; @count = 0; end + def to_str; @count += 1; @str; end + def count; @count; end + end + def test_instance_variable_get o = Object.new o.instance_eval { @foo = :foo } @@ -167,6 +294,12 @@ class TestObject < Test::Unit::TestCase 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 = ToStrCounter.new + assert_equal(:foo, o.instance_variable_get(n)) + assert_equal(1, n.count) end def test_instance_variable_set @@ -176,6 +309,13 @@ class TestObject < Test::Unit::TestCase 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 = ToStrCounter.new + o.instance_variable_set(n, :bar) + assert_equal(:bar, o.instance_eval { @foo }) + assert_equal(1, n.count) end def test_instance_variable_defined @@ -186,31 +326,95 @@ class TestObject < Test::Unit::TestCase 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 = ToStrCounter.new + assert_equal(true, o.instance_variable_defined?(n)) + assert_equal(1, n.count) end def test_remove_instance_variable - o = Object.new - o.instance_eval { @foo = :foo } - o.remove_instance_variable(:@foo) - assert_equal(false, o.instance_variable_defined?(:@foo)) + { '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_type + def test_remove_instance_variable_re_embed + assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + c = Class.new do + attr_reader :a, :b, :c + + def initialize + @a = nil + @b = nil + @c = nil + end + end + + o1 = c.new + o2 = c.new + + o1.instance_variable_set(:@foo, 5) + o1.instance_variable_set(:@a, 0) + o1.instance_variable_set(:@b, 1) + o1.instance_variable_set(:@c, 2) + refute_includes ObjectSpace.dump(o1), '"embedded":true' + o1.remove_instance_variable(:@foo) + assert_includes ObjectSpace.dump(o1), '"embedded":true' + + o2.instance_variable_set(:@a, 0) + o2.instance_variable_set(:@b, 1) + o2.instance_variable_set(:@c, 2) + assert_includes ObjectSpace.dump(o2), '"embedded":true' + + assert_equal(0, o1.a) + assert_equal(1, o1.b) + assert_equal(2, o1.c) + assert_equal(0, o2.a) + assert_equal(1, o2.b) + assert_equal(2, o2.c) + end; + end + + def test_convert_string o = Object.new def o.to_s; 1; end assert_raise(TypeError) { String(o) } + o.singleton_class.remove_method(:to_s) 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_check_convert_type + def test_convert_array o = Object.new def o.to_a; 1; end assert_raise(TypeError) { Array(o) } + o.singleton_class.remove_method(:to_a) 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 @@ -224,6 +428,7 @@ class TestObject < Test::Unit::TestCase o = Object.new def o.to_hash; {a: 1, b: 2}; end assert_equal({a: 1, b: 2}, Hash(o)) + o.singleton_class.remove_method(:to_hash) def o.to_hash; 9; end assert_raise(TypeError) { Hash(o) } end @@ -232,6 +437,7 @@ class TestObject < Test::Unit::TestCase o = Object.new def o.to_i; nil; end assert_raise(TypeError) { Integer(o) } + o.singleton_class.remove_method(:to_i) def o.to_i; 42; end assert_equal(42, Integer(o)) def o.respond_to?(*) false; end @@ -254,15 +460,16 @@ class TestObject < Test::Unit::TestCase assert_equal(1+3+5+7+9, n) end - def test_add_method_under_safe4 - o = Object.new - assert_raise(SecurityError) do - Thread.new do - $SAFE = 4 - def o.foo - end - end.join - end + def test_max_shape_variation_with_performance_warnings + assert_in_out_err([], <<-INPUT, %w(), /The class Foo reached 8 shape variations, instance variables accesses will be slower and memory usage increased/) + $VERBOSE = false + Warning[:performance] = true + + class Foo; end + 10.times do |i| + Foo.new.instance_variable_set(:"@a\#{i}", nil) + end + INPUT end def test_redefine_method_under_verbose @@ -276,15 +483,30 @@ class TestObject < Test::Unit::TestCase end def test_redefine_method_which_may_case_serious_problem - assert_in_out_err([], <<-INPUT, [], /warning: redefining `object_id' may cause serious problems$/) - $VERBOSE = false - def (Object.new).object_id; end - INPUT + %w(object_id __id__ __send__).each do |m| + assert_in_out_err([], <<-INPUT, [], %r"warning: redefining '#{m}' may cause serious problems$") + $VERBOSE = false + def (Object.new).#{m}; end + INPUT - assert_in_out_err([], <<-INPUT, [], /warning: redefining `__send__' may cause serious problems$/) - $VERBOSE = false - def (Object.new).__send__; end - INPUT + assert_in_out_err([], <<-INPUT, [], %r"warning: redefining '#{m}' may cause serious problems$") + $VERBOSE = false + Class.new.define_method(:#{m}) {} + INPUT + + assert_in_out_err([], <<-INPUT, [], %r"warning: redefining '#{m}' may cause serious problems$") + $VERBOSE = false + Class.new.attr_reader(:#{m}) + INPUT + + assert_in_out_err([], <<-INPUT, [], %r"warning: redefining '#{m}' may cause serious problems$") + $VERBOSE = false + Class.new do + def foo; end + alias #{m} foo + end + INPUT + end bug10421 = '[ruby-dev:48691] [Bug #10421]' assert_in_out_err([], <<-INPUT, ["1"], [], bug10421) @@ -297,23 +519,9 @@ class TestObject < Test::Unit::TestCase end def test_remove_method - assert_raise(SecurityError) do - Thread.new do - $SAFE = 4 - Object.instance_eval { remove_method(:foo) } - end.join - end - - assert_raise(SecurityError) do - Thread.new do - $SAFE = 4 - Class.instance_eval { remove_method(:foo) } - end.join - end - c = Class.new c.freeze - assert_raise(RuntimeError) do + assert_raise(FrozenError) do c.instance_eval { remove_method(:foo) } end @@ -337,8 +545,8 @@ class TestObject < Test::Unit::TestCase 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), /warning: removing `#{m}' may cause serious problems$/) + %w(object_id __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}) } @@ -347,6 +555,19 @@ class TestObject < Test::Unit::TestCase 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 @@ -421,8 +642,8 @@ class TestObject < Test::Unit::TestCase 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(foo.respond_to?(:foobar)) - assert_equal(false, foo.respond_to?(:foobarbaz)) + assert_respond_to(foo, :foobar) + assert_not_respond_to(foo, :foobarbaz) assert_raise(NoMethodError) do foo.foobarbaz end @@ -478,7 +699,7 @@ class TestObject < Test::Unit::TestCase called = [] p.singleton_class.class_eval do - define_method(:respond_to?) do |a| + define_method(:respond_to?) do |a, priv = false| called << [:respond_to?, a] false end @@ -498,11 +719,10 @@ class TestObject < Test::Unit::TestCase end end - e = assert_raise(ArgumentError, '[bug:6000]') do + msg = 'respond_to? must accept 1 or 2 arguments (requires 3)' + assert_raise_with_message(ArgumentError, msg, '[bug:6000]') do [[p]].flatten end - - assert_equal('respond_to? must accept 1 or 2 arguments (requires 3)', e.message) end def test_method_missing_passed_block @@ -573,7 +793,7 @@ class TestObject < Test::Unit::TestCase end begin nil.public_send(o) { x = :ng } - rescue + rescue TypeError end assert_equal(:ok, x) end @@ -622,7 +842,7 @@ class TestObject < Test::Unit::TestCase e = assert_raise(NoMethodError) { o.never_defined_test_no_superclass_method } - assert_equal(m1, e.message, bug2312) + assert_equal(m1.lines.first, e.message.lines.first, bug2312) end def test_superclass_method @@ -667,89 +887,19 @@ class TestObject < Test::Unit::TestCase end end - def test_untrusted - obj = lambda { - $SAFE = 4 - x = Object.new - x.instance_eval { @foo = 1 } - x - }.call - assert_equal(true, obj.untrusted?) - assert_equal(true, obj.tainted?) - - x = Object.new - assert_equal(false, x.untrusted?) - assert_raise(SecurityError) do - lambda { - $SAFE = 4 - x.instance_eval { @foo = 1 } - }.call - end - - x = Object.new - x.taint - assert_raise(SecurityError) do - lambda { - $SAFE = 4 - x.instance_eval { @foo = 1 } - }.call - end - - x.untrust - assert_equal(true, x.untrusted?) - assert_nothing_raised do - lambda { - $SAFE = 4 - x.instance_eval { @foo = 1 } - }.call - end - - x.trust - assert_equal(false, x.untrusted?) - assert_raise(SecurityError) do - lambda { - $SAFE = 4 - x.instance_eval { @foo = 1 } - }.call - end - - a = Object.new - a.untrust - assert_equal(true, a.untrusted?) - b = a.dup - assert_equal(true, b.untrusted?) - c = a.clone - assert_equal(true, c.untrusted?) - - a = Object.new - b = lambda { - $SAFE = 4 - a.dup - }.call - assert_equal(true, b.untrusted?) - - a = Object.new - b = lambda { - $SAFE = 4 - a.clone - }.call - assert_equal(true, b.untrusted?) - end - def test_to_s - x = Object.new - x.taint - x.untrust - s = x.to_s - assert_equal(true, s.untrusted?) - assert_equal(true, s.tainted?) - 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 @@ -768,6 +918,15 @@ class TestObject < Test::Unit::TestCase x.instance_variable_set(:@bar, 42) assert_match(/\A#<Object:0x\h+ (?:@foo="value", @bar=42|@bar=42, @foo="value")>\z/, x.inspect) + # Bug: [ruby-core:19167] + x = Object.new + x.instance_variable_set(:@foo, NilClass) + assert_match(/\A#<Object:0x\h+ @foo=NilClass>\z/, x.inspect) + x.instance_variable_set(:@foo, TrueClass) + assert_match(/\A#<Object:0x\h+ @foo=TrueClass>\z/, x.inspect) + x.instance_variable_set(:@foo, FalseClass) + assert_match(/\A#<Object:0x\h+ @foo=FalseClass>\z/, x.inspect) + # #inspect does not call #to_s anymore feature6130 = '[ruby-core:43238]' x = Object.new @@ -788,46 +947,48 @@ class TestObject < Test::Unit::TestCase def initialize @\u{3044} = 42 end - new.inspect + new end EOS - assert_match(/\bInspect\u{3042}:.* @\u{3044}=42\b/, x) - end - - def test_exec_recursive - Thread.current[:__recursive_key__] = nil - a = [[]] - a.inspect + 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) - assert_nothing_raised do - -> do - $SAFE = 4 - begin - a.hash - rescue ArgumentError - end - end.call + x = Object.new + x.singleton_class.class_eval do + private def instance_variables_to_inspect = [:@host, :@user] end - -> do - assert_nothing_raised do - $SAFE = 4 - a.inspect - end - end.call + x.instance_variable_set(:@host, "localhost") + x.instance_variable_set(:@user, "root") + x.instance_variable_set(:@password, "hunter2") + s = x.inspect + assert_include(s, "@host=\"localhost\"") + assert_include(s, "@user=\"root\"") + assert_not_include(s, "@password=") + end - -> do - o = Object.new - def o.to_ary(x); end - def o.==(x); $SAFE = 4; false; end - a = [[o]] - b = [] - b << b - - assert_nothing_raised do - b == a - end - end.call + 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 @@ -851,21 +1012,33 @@ class TestObject < Test::Unit::TestCase end end + def test_singleton_class_freeze + x = Object.new + xs = x.singleton_class + x.freeze + assert_predicate(xs, :frozen?) + + y = Object.new + ys = y.singleton_class + ys.prepend(Module.new) + y.freeze + assert_predicate(ys, :frozen?, '[Bug #19169]') + end + def test_redef_method_missing bug5473 = '[ruby-core:40287]' ['ArgumentError.new("bug5473")', 'ArgumentError, "bug5473"', '"bug5473"'].each do |code| - out, err, status = EnvUtil.invoke_ruby([], <<-SRC, true, true) + exc = code[/\A[A-Z]\w+/] || 'RuntimeError' + assert_separately([], <<-SRC) + $VERBOSE = nil class ::Object def method_missing(m, *a, &b) raise #{code} end end - p((1.foo rescue $!)) + assert_raise_with_message(#{exc}, "bug5473", #{bug5473.dump}) {1.foo} SRC - assert_send([status, :success?], bug5473) - assert_equal("", err, bug5473) - assert_equal((eval("raise #{code}") rescue $!.inspect), out.chomp, bug5473) end end @@ -874,14 +1047,8 @@ class TestObject < Test::Unit::TestCase b = yield assert_nothing_raised("copy") {a.instance_eval {initialize_copy(b)}} c = a.dup.freeze - assert_raise(RuntimeError, "frozen") {c.instance_eval {initialize_copy(b)}} - d = a.dup.trust - assert_raise(SecurityError, "untrust") do - proc { - $SAFE = 4 - d.instance_eval {initialize_copy(b)} - }.call - end + assert_raise(FrozenError, "frozen") {c.instance_eval {initialize_copy(b)}} + d = a.dup [a, b, c, d] end @@ -901,20 +1068,38 @@ class TestObject < Test::Unit::TestCase end def test_type_error_message - issue = "Bug #7539" - err = assert_raise(TypeError){ Integer([42]) } - assert_equal "can't convert Array into Integer", err.message, issue - err = assert_raise(TypeError){ [].first([42]) } - assert_equal 'no implicit conversion of Array into Integer', err.message, issue + _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, rss: true, timeout: 60) + 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_frozen_inspect + obj = Object.new + obj.instance_variable_set(:@a, "a") + ins = obj.inspect + obj.freeze + + assert_equal(ins, obj.inspect) + end end |
