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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
require 'test/unit'
require 'test/test_helper'
require 'tempfile'
require 'rbconfig'
require 'jruby'
#
# Find the name of the interpreter.
# FIXME: This should be moved to a common location.
#WINDOWS = RbConfig::CONFIG['host_os'] =~ /Windows|mswin/
#SEPARATOR = WINDOWS ? '\\' : '/'
#bin = RbConfig::CONFIG['bindir'].gsub('/', SEPARATOR)
#$interpreter = [bin, RbConfig::CONFIG['ruby_install_name']].join(SEPARATOR)
class TestObjectSpace < Test::Unit::TestCase
include TestHelper
#
# Check that two arrays contain the same "bag" of elements.
# A mathematical bag differs from a "set" by counting the
# occurences of each element. So as a bag [1,2,1] differs from
# [2,1] (but is equal to [1,1,2]).
#
# The method only relies on the == operator to match objects
# from the two arrays. The elements of the arrays may contain
# objects that are not "Comparable".
#
# FIXME: This should be moved to common location.
def assert_bag_equal(expected, actual)
# For each object in "actual" we remove an equal object
# from "expected". If we can match objects pairwise from the
# two arrays we have two equal "bags". The method Array#index
# uses == internally. We operate on a copy of "expected" to
# avoid destructively changing the argument.
#
expected_left = expected.dup
actual.each do |x|
if j = expected_left.index(x)
expected_left.slice!(j)
end
end
assert( expected.length == actual.length && expected_left.length == 0,
"Expected: #{expected.inspect}, Actual: #{actual.inspect}")
end
def test_s__id2ref
skip("object space is not enabled") unless JRuby.runtime.object_space_enabled?
s = "hello"
t = ObjectSpace._id2ref(s.__id__)
assert_equal(s, t)
assert_equal(s.__id__, t.__id__)
end
# finalizer manipulation
def test_s_finalizers
tf = Tempfile.new("tf")
begin
tf.puts %{
a = "string"
ObjectSpace.define_finalizer(a) { puts "OK" }
}
tf.close
if ENV['OS'] =~ /\AWin/
command = %{#{interpreter} "#{tf.path}"}
else
command = %{#{interpreter} #{tf.path}}
end
IO.popen(command) do |p|
assert_equal("OK", p.gets.chomp)
end
ensure
tf.close(true) rescue nil
end
end
class A; end
class B < A; end
class C < A; end
class D < C; end
def test_s_each_object
skip("object space is not enabled") unless JRuby.runtime.object_space_enabled?
a = A.new
b = B.new
c = C.new
d = D.new
res = []
ObjectSpace.each_object(TestObjectSpace::A) { |o| res << o }
assert_bag_equal([a, b, c, d], res)
res = []
ObjectSpace.each_object(B) { |o| res << o }
assert_bag_equal([b], res)
res = []
ObjectSpace.each_object(C) { |o| res << o }
assert_bag_equal([c, d], res)
end
# Demonstrate NPE referencing gc'ed var in conditional (JRUBY-1125)
def test_object_ref_goes_away
# make an object
x = 'xxx'
# save the id
n = x.object_id
# nil the reference
x = nil
# force GC (and wait until var is gone)
t = Time.now
(JRuby.gc; sleep 0.1) until (ObjectSpace._id2ref(n).nil? || (Time.now - t > 5))
# straight reference should succeed
assert_nil(ObjectSpace._id2ref n)
# reference in conditional caused NPE
assert_nothing_raised {
if ObjectSpace._id2ref n
end
}
end
end
|