summaryrefslogtreecommitdiff
path: root/test/ruby/test_objectspace.rb
blob: de7c6be916feba94fbe489330b39720e18fb8fcb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
require 'test/unit'
require_relative 'envutil'

class TestObjectSpace < Test::Unit::TestCase
  def self.deftest_id2ref(obj)
    /:(\d+)/ =~ caller[0]
    file = $`
    line = $1.to_i
    code = <<"End"
    define_method("test_id2ref_#{line}") {\
      o = ObjectSpace._id2ref(obj.object_id);\
      assert_same(obj, o, "didn't round trip: \#{obj.inspect}");\
    }
End
    eval code, binding, file, line
  end

  deftest_id2ref(-0x4000000000000001)
  deftest_id2ref(-0x4000000000000000)
  deftest_id2ref(-0x40000001)
  deftest_id2ref(-0x40000000)
  deftest_id2ref(-1)
  deftest_id2ref(0)
  deftest_id2ref(1)
  deftest_id2ref(0x3fffffff)
  deftest_id2ref(0x40000000)
  deftest_id2ref(0x3fffffffffffffff)
  deftest_id2ref(0x4000000000000000)
  deftest_id2ref(:a)
  deftest_id2ref(:abcdefghijilkjl)
  deftest_id2ref(:==)
  deftest_id2ref(Object.new)
  deftest_id2ref(self)
  deftest_id2ref(true)
  deftest_id2ref(false)
  deftest_id2ref(nil)

  def test_count_objects
    h = {}
    ObjectSpace.count_objects(h)
    assert_kind_of(Hash, h)
    assert_empty(h.keys.delete_if {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
    assert_empty(h.values.delete_if {|x| x.is_a?(Integer) })

    h = ObjectSpace.count_objects
    assert_kind_of(Hash, h)
    assert_empty(h.keys.delete_if {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
    assert_empty(h.values.delete_if {|x| x.is_a?(Integer) })

    assert_raise(TypeError) { ObjectSpace.count_objects(1) }

    h0 = {:T_FOO=>1000}
    h = ObjectSpace.count_objects(h0)
    assert_same(h0, h)
    assert_equal(0, h0[:T_FOO])
  end

  def test_finalizer
    assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok :ok), [])
      a = []
      ObjectSpace.define_finalizer(a) { p :ok }
      b = a.dup
      ObjectSpace.define_finalizer(a) { p :ok }
      !b
    END
    assert_raise(ArgumentError) { ObjectSpace.define_finalizer([], Object.new) }

    code = proc do |priv|
      <<-"CODE"
      fin = Object.new
      class << fin
        #{priv}def call(id)
          puts "finalized"
        end
      end
      ObjectSpace.define_finalizer([], fin)
      CODE
    end
    assert_in_out_err([], code[""], ["finalized"])
    assert_in_out_err([], code["private "], ["finalized"])
    c = EnvUtil.labeled_class("C\u{3042}").new
    o = Object.new
    assert_raise_with_message(ArgumentError, /C\u{3042}/) {
      ObjectSpace.define_finalizer(o, c)
    }
  end

  def test_each_object
    assert_separately([], <<-End)
    GC.disable
    eval('begin; 1.times{}; rescue; ensure; end')
    arys = []
    ObjectSpace.each_object(Array){|ary|
      arys << ary
    }
    GC.enable
    arys.each{|ary|
      begin
        assert_equal(String, ary.inspect.class) # should not cause SEGV
      rescue RuntimeError
        # rescue "can't modify frozen File" error.
      end
    }
    End
  end
end