diff options
Diffstat (limited to 'jni/ruby/test/-ext-')
56 files changed, 3297 insertions, 0 deletions
diff --git a/jni/ruby/test/-ext-/array/test_resize.rb b/jni/ruby/test/-ext-/array/test_resize.rb new file mode 100644 index 0000000..8e526b5 --- /dev/null +++ b/jni/ruby/test/-ext-/array/test_resize.rb @@ -0,0 +1,29 @@ +require 'test/unit' +require '-test-/array/resize' + +class TestArray < Test::Unit::TestCase + class TestResize < Test::Unit::TestCase + def test_expand + feature = '[ruby-dev:42912]' + ary = [*1..10] + ary.__resize__(10) + assert_equal(10, ary.size, feature) + assert_equal([*1..10], ary, feature) + ary.__resize__(100) + assert_equal(100, ary.size, feature) + assert_equal([*1..10]+[nil]*90, ary, feature) + ary.__resize__(20) + assert_equal(20, ary.size, feature) + assert_equal([*1..10]+[nil]*10, ary, feature) + ary.__resize__(2) + assert_equal(2, ary.size, feature) + assert_equal([1,2], ary, feature) + ary.__resize__(3) + assert_equal(3, ary.size, feature) + assert_equal([1,2,nil], ary, feature) + ary.__resize__(10) + assert_equal(10, ary.size, feature) + assert_equal([1,2]+[nil]*8, ary, feature) + end + end +end diff --git a/jni/ruby/test/-ext-/bignum/test_big2str.rb b/jni/ruby/test/-ext-/bignum/test_big2str.rb new file mode 100644 index 0000000..0af552e --- /dev/null +++ b/jni/ruby/test/-ext-/bignum/test_big2str.rb @@ -0,0 +1,29 @@ +require 'test/unit' +require "-test-/bignum" + +class TestBignum < Test::Unit::TestCase + class TestBig2str < Test::Unit::TestCase + + SIZEOF_BDIGIT = Bignum::SIZEOF_BDIGIT + BITSPERDIG = Bignum::BITSPERDIG + BDIGMAX = (1 << BITSPERDIG) - 1 + + def test_big2str_generic + x = 10**1000 + assert_equal("1" + "0" * 1000, x.big2str_generic(10)) + end + + def test_big2str_poweroftwo + e = BITSPERDIG*2 + x = 0b10**e + assert_equal("1" + "0" * e, x.big2str_poweroftwo(2)) + end + + def test_big2str_gmp + x = 10**1000 + assert_equal("1" + "0" * 1000, x.big2str_gmp(10)) + rescue NotImplementedError + end + + end +end diff --git a/jni/ruby/test/-ext-/bignum/test_bigzero.rb b/jni/ruby/test/-ext-/bignum/test_bigzero.rb new file mode 100644 index 0000000..f75c459 --- /dev/null +++ b/jni/ruby/test/-ext-/bignum/test_bigzero.rb @@ -0,0 +1,13 @@ +require 'test/unit' +require "-test-/bignum" + +class TestBignum < Test::Unit::TestCase + class TestBigZero < Test::Unit::TestCase + def test_equal_0 + bug8204 = '[ruby-core:53893] [Bug #8204]' + (0..10).each do |i| + assert_equal(0, Bug::Bignum.zero(i), "#{bug8204} Bignum.zero(#{i})") + end + end + end +end diff --git a/jni/ruby/test/-ext-/bignum/test_div.rb b/jni/ruby/test/-ext-/bignum/test_div.rb new file mode 100644 index 0000000..9c1a3c3 --- /dev/null +++ b/jni/ruby/test/-ext-/bignum/test_div.rb @@ -0,0 +1,28 @@ +require 'test/unit' +require "-test-/bignum" + +class TestBignum < Test::Unit::TestCase + class TestDiv < Test::Unit::TestCase + + SIZEOF_BDIGIT = Bignum::SIZEOF_BDIGIT + BITSPERDIG = Bignum::BITSPERDIG + BDIGMAX = (1 << BITSPERDIG) - 1 + + def test_divrem_normal + x = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 3 + y = (1 << BITSPERDIG) | 1 + q = (1 << BITSPERDIG) | 1 + r = 2 + assert_equal([q, r], x.big_divrem_normal(y)) + end + + def test_divrem_gmp + x = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 3 + y = (1 << BITSPERDIG) | 1 + q = (1 << BITSPERDIG) | 1 + r = 2 + assert_equal([q, r], x.big_divrem_gmp(y)) + rescue NotImplementedError + end + end +end diff --git a/jni/ruby/test/-ext-/bignum/test_mul.rb b/jni/ruby/test/-ext-/bignum/test_mul.rb new file mode 100644 index 0000000..3e78247 --- /dev/null +++ b/jni/ruby/test/-ext-/bignum/test_mul.rb @@ -0,0 +1,137 @@ +require 'test/unit' +require "-test-/bignum" + +class TestBignum < Test::Unit::TestCase + class TestMul < Test::Unit::TestCase + + SIZEOF_BDIGIT = Bignum::SIZEOF_BDIGIT + BITSPERDIG = Bignum::BITSPERDIG + BDIGMAX = (1 << BITSPERDIG) - 1 + + def test_mul_normal + x = (1 << BITSPERDIG) | 1 + y = (1 << BITSPERDIG) | 1 + z = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 1 + assert_equal(z, x.big_mul_normal(y)) + end + + def test_mul_normal_zero_in_x + x = (1 << (2*BITSPERDIG)) | 1 + y = (1 << BITSPERDIG) | 1 + z = (1 << (BITSPERDIG*3)) | (1 << (BITSPERDIG*2)) | (1 << BITSPERDIG) | 1 + assert_equal(z, x.big_mul_normal(y)) + end + + def test_mul_normal_zero_in_y + x = (1 << BITSPERDIG) | 1 + y = (1 << (2*BITSPERDIG)) | 1 + z = (1 << (BITSPERDIG*3)) | (1 << (BITSPERDIG*2)) | (1 << BITSPERDIG) | 1 + assert_equal(z, x.big_mul_normal(y)) + end + + def test_mul_normal_max_max + x = (1 << (2*BITSPERDIG)) - 1 + y = (1 << (2*BITSPERDIG)) - 1 + z = (1 << (4*BITSPERDIG)) - (1 << (2*BITSPERDIG+1)) + 1 + assert_equal(z, x.big_mul_normal(y)) + end + + def test_sq_fast + x = (1 << BITSPERDIG) | 1 + z = (1 << 2*BITSPERDIG) | (2 << BITSPERDIG) | 1 + assert_equal(z, x.big_sq_fast) + end + + def test_sq_fast_max2 + x = (BDIGMAX << BITSPERDIG) | BDIGMAX + assert_equal(x.big_mul_normal(x), x.big_sq_fast) + end + + def test_sq_fast_zero_in_middle + x = (BDIGMAX << 2*BITSPERDIG) | BDIGMAX + assert_equal(x.big_mul_normal(x), x.big_sq_fast) + end + + def test_mul_balance + x = (1 << BITSPERDIG) | 1 + y = (1 << BITSPERDIG) | 1 + z = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 1 + assert_equal(z, x.big_mul_balance(y)) + end + + def test_mul_balance_2x16 + x = (1 << Bignum::BITSPERDIG) | 1 + y = (1 << Bignum::BITSPERDIG*16) | 1 + assert_equal(x.big_mul_normal(y), x.big_mul_balance(y)) + end + + def test_mul_balance_2x17 + x = (1 << Bignum::BITSPERDIG) | 1 + y = (1 << Bignum::BITSPERDIG*17) | 1 + assert_equal(x.big_mul_normal(y), x.big_mul_balance(y)) + end + + def test_mul_karatsuba + x = (1 << BITSPERDIG) | 1 + y = (1 << BITSPERDIG) | 1 + z = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 1 + assert_equal(z, x.big_mul_karatsuba(y)) + end + + def test_mul_karatsuba_odd_y + x = (1 << BITSPERDIG) | 1 + y = (1 << (2*BITSPERDIG)) | 1 + assert_equal(x.big_mul_normal(y), x.big_mul_karatsuba(y)) + end + + def test_mul_karatsuba_odd_xy + x = (1 << (2*BITSPERDIG)) | 1 + y = (1 << (2*BITSPERDIG)) | 1 + assert_equal(x.big_mul_normal(y), x.big_mul_karatsuba(y)) + end + + def test_mul_karatsuba_x1_gt_x0 + x = (2 << BITSPERDIG) | 1 + y = (1 << BITSPERDIG) | 2 + assert_equal(x.big_mul_normal(y), x.big_mul_karatsuba(y)) + end + + def test_mul_karatsuba_y1_gt_y0 + x = (1 << BITSPERDIG) | 2 + y = (2 << BITSPERDIG) | 1 + assert_equal(x.big_mul_normal(y), x.big_mul_karatsuba(y)) + end + + def test_mul_karatsuba_x1_gt_x0_and_y1_gt_y0 + x = (2 << BITSPERDIG) | 1 + y = (2 << BITSPERDIG) | 1 + assert_equal(x.big_mul_normal(y), x.big_mul_karatsuba(y)) + end + + def test_mul_karatsuba_carry2 + x = (1 << BITSPERDIG) | BDIGMAX + y = (1 << BITSPERDIG) | BDIGMAX + assert_equal(x.big_mul_normal(y), x.big_mul_karatsuba(y)) + end + + def test_mul_karatsuba_borrow + x = (BDIGMAX << BITSPERDIG) | 1 + y = (BDIGMAX << BITSPERDIG) | 1 + assert_equal(x.big_mul_normal(y), x.big_mul_karatsuba(y)) + end + + def test_mul_toom3 + x = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1 + y = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1 + assert_equal(x.big_mul_normal(y), x.big_mul_toom3(y)) + end + + def test_mul_gmp + x = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1 + y = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1 + assert_equal(x.big_mul_normal(y), x.big_mul_gmp(y)) + rescue NotImplementedError + end + + end +end diff --git a/jni/ruby/test/-ext-/bignum/test_pack.rb b/jni/ruby/test/-ext-/bignum/test_pack.rb new file mode 100644 index 0000000..f2a3df8 --- /dev/null +++ b/jni/ruby/test/-ext-/bignum/test_pack.rb @@ -0,0 +1,398 @@ +# coding: ASCII-8BIT + +require 'test/unit' +require "-test-/bignum" + +class TestBignum < Test::Unit::TestCase + class TestPack < Test::Unit::TestCase + + MSWORD_FIRST = Integer::INTEGER_PACK_MSWORD_FIRST + LSWORD_FIRST = Integer::INTEGER_PACK_LSWORD_FIRST + MSBYTE_FIRST = Integer::INTEGER_PACK_MSBYTE_FIRST + LSBYTE_FIRST = Integer::INTEGER_PACK_LSBYTE_FIRST + NATIVE_BYTE_ORDER = Integer::INTEGER_PACK_NATIVE_BYTE_ORDER + TWOCOMP = Integer::INTEGER_PACK_2COMP + LITTLE_ENDIAN = Integer::INTEGER_PACK_LITTLE_ENDIAN + BIG_ENDIAN = Integer::INTEGER_PACK_BIG_ENDIAN + NEGATIVE = Integer::INTEGER_PACK_NEGATIVE + GENERIC = Integer::INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION + + def test_pack_zero + assert_equal([0, ""], 0.test_pack(0, 1, 0, BIG_ENDIAN)) + end + + def test_pack_argument_check + assert_raise(ArgumentError) { 0.test_pack_raw("", 2, 1, 0, MSBYTE_FIRST) } + assert_raise(ArgumentError) { 0.test_pack_raw("", 0, 1, 0, MSWORD_FIRST) } + assert_raise(ArgumentError) { 0.test_pack_raw("", 0, 0, 0, BIG_ENDIAN) } + assert_raise(ArgumentError) { 0.test_pack_raw("", 0, 1, 8, BIG_ENDIAN) } + + # assume sizeof(ssize_t) == sizeof(intptr_t) + assert_raise(ArgumentError) { 0.test_pack_raw("", 1 << ([""].pack("p").length * 8 - 1), 0, BIG_ENDIAN) } + end + + def test_pack_wordsize + assert_equal([1, "\x01"], 1.test_pack(1, 1, 0, BIG_ENDIAN)) + assert_equal([1, "\x00\x01"], 1.test_pack(1, 2, 0, BIG_ENDIAN)) + assert_equal([1, "\x00\x00\x01"], 1.test_pack(1, 3, 0, BIG_ENDIAN)) + assert_equal([1, "\x01"], 1.test_pack(1, 1, 0, LITTLE_ENDIAN)) + assert_equal([1, "\x01\x00"], 1.test_pack(1, 2, 0, LITTLE_ENDIAN)) + assert_equal([1, "\x01\x00\x00"], 1.test_pack(1, 3, 0, LITTLE_ENDIAN)) + end + + def test_pack_fixed_buffer + assert_equal([0, "\x00\x00"], 0.test_pack(2, 1, 0, BIG_ENDIAN)) + assert_equal([1, "\x00\x01"], 0x01.test_pack(2, 1, 0, BIG_ENDIAN)) + assert_equal([1, "\x02\x01"], 0x0201.test_pack(2, 1, 0, BIG_ENDIAN)) + assert_equal([2, "\x02\x01"], 0x030201.test_pack(2, 1, 0, BIG_ENDIAN)) + assert_equal([2, "\x02\x01"], 0x04030201.test_pack(2, 1, 0, BIG_ENDIAN)) + assert_equal([0, "\x00\x00"], 0.test_pack(2, 1, 0, LITTLE_ENDIAN)) + assert_equal([1, "\x01\x00"], 0x01.test_pack(2, 1, 0, LITTLE_ENDIAN)) + assert_equal([1, "\x01\x02"], 0x0201.test_pack(2, 1, 0, LITTLE_ENDIAN)) + assert_equal([2, "\x01\x02"], 0x030201.test_pack(2, 1, 0, LITTLE_ENDIAN)) + assert_equal([2, "\x01\x02"], 0x04030201.test_pack(2, 1, 0, LITTLE_ENDIAN)) + end + + def test_pack_wordorder_and_endian + assert_equal([1, "\x12\x34\x56\x78"], 0x12345678.test_pack(2, 2, 0, MSWORD_FIRST|MSBYTE_FIRST)) + assert_equal([1, "\x34\x12\x78\x56"], 0x12345678.test_pack(2, 2, 0, MSWORD_FIRST|LSBYTE_FIRST)) + assert_equal([1, "\x56\x78\x12\x34"], 0x12345678.test_pack(2, 2, 0, LSWORD_FIRST|MSBYTE_FIRST)) + assert_equal([1, "\x78\x56\x34\x12"], 0x12345678.test_pack(2, 2, 0, LSWORD_FIRST|LSBYTE_FIRST)) + end + + def test_pack_native_endian + assert_equal([1, [0x1234].pack("S!")], 0x1234.test_pack(1, 2, 0, MSWORD_FIRST|NATIVE_BYTE_ORDER)) + end + + def test_pack_nail + assert_equal([1, "\x01\x00\x00\x00\x01\x01"], 0b100011.test_pack(6, 1, 7, BIG_ENDIAN)) + assert_equal([1, "\x01\x02\x03\x04\x05\x06\x07\x08"], 0x12345678.test_pack(8, 1, 4, BIG_ENDIAN)) + assert_equal([1, "\x00\x12\x00\x34\x00\x56\x00\x78"], 0x12345678.test_pack(4, 2, 8, BIG_ENDIAN)) + end + + def test_pack_overflow + assert_equal([-2, "\x1"], (-0x11).test_pack(1, 1, 4, BIG_ENDIAN)) + assert_equal([-2, "\x0"], (-0x10).test_pack(1, 1, 4, BIG_ENDIAN)) + assert_equal([-1, "\xF"], (-0x0F).test_pack(1, 1, 4, BIG_ENDIAN)) + assert_equal([+1, "\xF"], (+0x0F).test_pack(1, 1, 4, BIG_ENDIAN)) + assert_equal([+2, "\x0"], (+0x10).test_pack(1, 1, 4, BIG_ENDIAN)) + assert_equal([+2, "\x1"], (+0x11).test_pack(1, 1, 4, BIG_ENDIAN)) + + assert_equal([-2, "\x01"], (-0x101).test_pack(1, 1, 0, BIG_ENDIAN)) + assert_equal([-2, "\x00"], (-0x100).test_pack(1, 1, 0, BIG_ENDIAN)) + assert_equal([-1, "\xFF"], (-0x0FF).test_pack(1, 1, 0, BIG_ENDIAN)) + assert_equal([+1, "\xFF"], (+0x0FF).test_pack(1, 1, 0, BIG_ENDIAN)) + assert_equal([+2, "\x00"], (+0x100).test_pack(1, 1, 0, BIG_ENDIAN)) + assert_equal([+2, "\x01"], (+0x101).test_pack(1, 1, 0, BIG_ENDIAN)) + + assert_equal([-2, "\x00\x00\x00\x00\x00\x00\x00\x01"], (-0x10000000000000001).test_pack(2, 4, 0, BIG_ENDIAN)) + assert_equal([-2, "\x00\x00\x00\x00\x00\x00\x00\x00"], (-0x10000000000000000).test_pack(2, 4, 0, BIG_ENDIAN)) + assert_equal([-1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], (-0x0FFFFFFFFFFFFFFFF).test_pack(2, 4, 0, BIG_ENDIAN)) + assert_equal([+1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], (+0x0FFFFFFFFFFFFFFFF).test_pack(2, 4, 0, BIG_ENDIAN)) + assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x00"], (+0x10000000000000000).test_pack(2, 4, 0, BIG_ENDIAN)) + assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x01"], (+0x10000000000000001).test_pack(2, 4, 0, BIG_ENDIAN)) + + 1.upto(16) {|wordsize| + 1.upto(20) {|numwords| + w = numwords*wordsize + n = 256**w + assert_equal([-2, "\x00"*(w-1)+"\x01"], (-n-1).test_pack(numwords, wordsize, 0, BIG_ENDIAN)) + assert_equal([-2, "\x00"*w], (-n ).test_pack(numwords, wordsize, 0, BIG_ENDIAN)) + assert_equal([-1, "\xFF"*w], (-n+1).test_pack(numwords, wordsize, 0, BIG_ENDIAN)) + assert_equal([+1, "\xFF"*w], (+n-1).test_pack(numwords, wordsize, 0, BIG_ENDIAN)) + assert_equal([+2, "\x00"*w], (+n ).test_pack(numwords, wordsize, 0, BIG_ENDIAN)) + assert_equal([+2, "\x00"*(w-1)+"\x01"], (+n+1).test_pack(numwords, wordsize, 0, BIG_ENDIAN)) + } + } + + 1.upto(16) {|wordsize| + 1.upto(20) {|numwords| + w = numwords*wordsize + n = 256**w + assert_equal([-2, "\x01"+"\x00"*(w-1)], (-n-1).test_pack(numwords, wordsize, 0, LITTLE_ENDIAN)) + assert_equal([-2, "\x00"*w], (-n ).test_pack(numwords, wordsize, 0, LITTLE_ENDIAN)) + assert_equal([-1, "\xFF"*w], (-n+1).test_pack(numwords, wordsize, 0, LITTLE_ENDIAN)) + assert_equal([+1, "\xFF"*w], (+n-1).test_pack(numwords, wordsize, 0, LITTLE_ENDIAN)) + assert_equal([+2, "\x00"*w], (+n ).test_pack(numwords, wordsize, 0, LITTLE_ENDIAN)) + assert_equal([+2, "\x01"+"\x00"*(w-1)], (+n+1).test_pack(numwords, wordsize, 0, LITTLE_ENDIAN)) + } + } + end + + def test_pack_sign + assert_equal([-1, "\x01"], (-1).test_pack(1, 1, 0, BIG_ENDIAN)) + assert_equal([-1, "\x80\x70\x60\x50\x40\x30\x20\x10"], (-0x8070605040302010).test_pack(8, 1, 0, BIG_ENDIAN)) + end + + def test_pack_orders + [MSWORD_FIRST, LSWORD_FIRST].each {|word_order| + [MSBYTE_FIRST, LSBYTE_FIRST, NATIVE_BYTE_ORDER].each {|byte_order| + 1.upto(16) {|wordsize| + 1.upto(20) {|numwords| + w = numwords*wordsize + n = 0; + 0.upto(w) {|i| + n |= ((i+1) % 256) << (i*8) + } + assert_equal(n.test_pack(numwords, wordsize, 0, word_order|byte_order|GENERIC), + n.test_pack(numwords, wordsize, 0, word_order|byte_order), + "#{'%#x' % n}.test_pack(#{numwords}, #{wordsize}, 0, #{'%#x' % (word_order|byte_order)})") + } + } + } + } + end + + def test_pack2comp_zero + assert_equal([0, ""], 0.test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN)) + end + + def test_pack2comp_emptybuf + assert_equal([-2, ""], (-3).test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([-2, ""], (-2).test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, ""], (-1).test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([ 0, ""], 0.test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, ""], 1.test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, ""], 2.test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN)) + end + + def test_pack2comp_nearly_zero + assert_equal([-1, "\xFE"], (-2).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, "\xFF"], (-1).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([ 0, "\x00"], 0.test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+1, "\x01"], 1.test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+1, "\x02"], 2.test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + end + + def test_pack2comp_overflow + assert_equal([-2, "\xF"], (-0x11).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, "\x0"], (-0x10).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, "\x1"], (-0x0F).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN)) + assert_equal([+1, "\xF"], (+0x0F).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, "\x0"], (+0x10).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, "\x1"], (+0x11).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN)) + + assert_equal([-2, "\xFF"], (-0x101).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, "\x00"], (-0x100).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, "\x01"], (-0x0FF).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+1, "\xFF"], (+0x0FF).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, "\x00"], (+0x100).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, "\x01"], (+0x101).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN)) + + assert_equal([-2, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], (-0x10000000000000001).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x00"], (-0x10000000000000000).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x01"], (-0x0FFFFFFFFFFFFFFFF).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], (+0x0FFFFFFFFFFFFFFFF).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x00"], (+0x10000000000000000).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x01"], (+0x10000000000000001).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN)) + + 1.upto(16) {|wordsize| + 1.upto(20) {|numwords| + w = numwords*wordsize + n = 256**w + assert_equal([-2, "\xFF"*w ], (-n-1).test_pack(numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, "\x00"*w], (-n ).test_pack(numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([-1, "\x00"*(w-1)+"\x01"], (-n+1).test_pack(numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+1, "\xFF"*w], (+n-1).test_pack(numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, "\x00"*w], (+n ).test_pack(numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal([+2, "\x00"*(w-1)+"\x01"], (+n+1).test_pack(numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN)) + } + } + + 1.upto(16) {|wordsize| + 1.upto(20) {|numwords| + w = numwords*wordsize + n = 256**w + assert_equal([-2, "\xFF"*w ], (-n-1).test_pack(numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN)) + assert_equal([-1, "\x00"*w], (-n ).test_pack(numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN)) + assert_equal([-1, "\x01"+"\x00"*(w-1)], (-n+1).test_pack(numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN)) + assert_equal([+1, "\xFF"*w], (+n-1).test_pack(numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN)) + assert_equal([+2, "\x00"*w], (+n ).test_pack(numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN)) + assert_equal([+2, "\x01"+"\x00"*(w-1)], (+n+1).test_pack(numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN)) + } + } + + 2.upto(16) {|wordsize| + w = wordsize + b = 8*wordsize-1 + n = 2**b + assert_equal([-2, "\x7F"+"\xFF"*(w-2)+"\xFF"], (-n-1).test_pack(1, wordsize, 1, TWOCOMP|MSBYTE_FIRST)) + assert_equal([-1, "\x00"+"\x00"*(w-2)+"\x00"], (-n ).test_pack(1, wordsize, 1, TWOCOMP|MSBYTE_FIRST)) + assert_equal([-1, "\x00"+"\x00"*(w-2)+"\x01"], (-n+1).test_pack(1, wordsize, 1, TWOCOMP|MSBYTE_FIRST)) + assert_equal([+1, "\x7F"+"\xFF"*(w-2)+"\xFF"], (+n-1).test_pack(1, wordsize, 1, TWOCOMP|MSBYTE_FIRST)) + assert_equal([+2, "\x00"+"\x00"*(w-2)+"\x00"], (+n ).test_pack(1, wordsize, 1, TWOCOMP|MSBYTE_FIRST)) + assert_equal([+2, "\x00"+"\x00"*(w-2)+"\x01"], (+n+1).test_pack(1, wordsize, 1, TWOCOMP|MSBYTE_FIRST)) + } + + 2.upto(16) {|wordsize| + w = wordsize + b = 8*wordsize-1 + n = 2**b + assert_equal([-2, "\xFF"+"\xFF"*(w-2)+"\x7F"], (-n-1).test_pack(1, wordsize, 1, TWOCOMP|LSBYTE_FIRST)) + assert_equal([-1, "\x00"+"\x00"*(w-2)+"\x00"], (-n ).test_pack(1, wordsize, 1, TWOCOMP|LSBYTE_FIRST)) + assert_equal([-1, "\x01"+"\x00"*(w-2)+"\x00"], (-n+1).test_pack(1, wordsize, 1, TWOCOMP|LSBYTE_FIRST)) + assert_equal([+1, "\xFF"+"\xFF"*(w-2)+"\x7F"], (+n-1).test_pack(1, wordsize, 1, TWOCOMP|LSBYTE_FIRST)) + assert_equal([+2, "\x00"+"\x00"*(w-2)+"\x00"], (+n ).test_pack(1, wordsize, 1, TWOCOMP|LSBYTE_FIRST)) + assert_equal([+2, "\x01"+"\x00"*(w-2)+"\x00"], (+n+1).test_pack(1, wordsize, 1, TWOCOMP|LSBYTE_FIRST)) + } + + end + + def test_unpack_zero + assert_equal(0, Integer.test_unpack("", 0, 1, 0, BIG_ENDIAN)) + end + + def test_unpack_argument_check + assert_raise(ArgumentError) { Integer.test_unpack("x", 2, 1, 0, MSBYTE_FIRST) } + assert_raise(ArgumentError) { Integer.test_unpack("x", 1, 1, 0, MSWORD_FIRST) } + assert_raise(ArgumentError) { Integer.test_unpack("x", 1, 0, 0, BIG_ENDIAN) } + assert_raise(ArgumentError) { Integer.test_unpack("x", 1, 1, 8, BIG_ENDIAN) } + + # assume sizeof(ssize_t) == sizeof(intptr_t) + assert_raise(ArgumentError) { Integer.test_unpack("x", 1, 1 << ([""].pack("p").length * 8 - 1), 0, BIG_ENDIAN) } + end + + def test_unpack_wordsize + assert_equal(1, Integer.test_unpack("\x01", 1, 1, 0, BIG_ENDIAN)) + assert_equal(1, Integer.test_unpack("\x00\x01", 1, 2, 0, BIG_ENDIAN)) + assert_equal(1, Integer.test_unpack("\x00\x00\x01", 1, 3, 0, BIG_ENDIAN)) + assert_equal(1, Integer.test_unpack("\x01", 1, 1, 0, LITTLE_ENDIAN)) + assert_equal(1, Integer.test_unpack("\x01\x00", 1, 2, 0, LITTLE_ENDIAN)) + assert_equal(1, Integer.test_unpack("\x01\x00\x00", 1, 3, 0, LITTLE_ENDIAN)) + end + + def test_unpack_wordorder_and_endian + assert_equal(0x01020304, Integer.test_unpack("\x01\x02\x03\x04", 2, 2, 0, MSWORD_FIRST|MSBYTE_FIRST)) + assert_equal(0x02010403, Integer.test_unpack("\x01\x02\x03\x04", 2, 2, 0, MSWORD_FIRST|LSBYTE_FIRST)) + assert_equal(0x03040102, Integer.test_unpack("\x01\x02\x03\x04", 2, 2, 0, LSWORD_FIRST|MSBYTE_FIRST)) + assert_equal(0x04030201, Integer.test_unpack("\x01\x02\x03\x04", 2, 2, 0, LSWORD_FIRST|LSBYTE_FIRST)) + end + + def test_unpack_native_endian + assert_equal("\x12\x34".unpack("S!")[0], Integer.test_unpack("\x12\x34", 1, 2, 0, MSWORD_FIRST|NATIVE_BYTE_ORDER)) + end + + def test_unpack_nail + assert_equal(0b100011, Integer.test_unpack("\x01\x00\x00\x00\x01\x01", 6, 1, 7, BIG_ENDIAN)) + assert_equal(0x12345678, Integer.test_unpack("\x01\x02\x03\x04\x05\x06\x07\x08", 8, 1, 4, BIG_ENDIAN)) + assert_equal(0x12345678, Integer.test_unpack("\x00\x12\x00\x34\x00\x56\x00\x78", 4, 2, 8, BIG_ENDIAN)) + end + + def test_unpack_sign + assert_equal(-1, Integer.test_unpack("\x01", 1, 1, 0, BIG_ENDIAN|NEGATIVE)) + assert_equal(-0x8070605040302010, Integer.test_unpack("\x80\x70\x60\x50\x40\x30\x20\x10", 8, 1, 0, BIG_ENDIAN|NEGATIVE)) + end + + def test_unpack_orders + [MSWORD_FIRST, LSWORD_FIRST].each {|word_order| + [MSBYTE_FIRST, LSBYTE_FIRST, NATIVE_BYTE_ORDER].each {|byte_order| + 1.upto(16) {|wordsize| + 1.upto(20) {|numwords| + w = numwords*wordsize + ary = [] + 0.upto(w) {|i| + ary << ((i+1) % 256); + } + str = ary.pack("C*") + flags = word_order|byte_order + assert_equal(Integer.test_unpack(str, numwords, wordsize, 0, flags|GENERIC), + Integer.test_unpack(str, numwords, wordsize, 0, flags), + "Integer.test_unpack(#{str.dump}, #{numwords}, #{wordsize}, 0, #{'%#x' % flags})") + } + } + } + } + end + + def test_unpack2comp_single_byte + assert_equal(-128, Integer.test_unpack("\x80", 1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal( -2, Integer.test_unpack("\xFE", 1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal( -1, Integer.test_unpack("\xFF", 1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal( 0, Integer.test_unpack("\x00", 1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal( 1, Integer.test_unpack("\x01", 1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal( 2, Integer.test_unpack("\x02", 1, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal( 127, Integer.test_unpack("\x7F", 1, 1, 0, TWOCOMP|BIG_ENDIAN)) + end + + def test_unpack2comp_sequence_of_ff + assert_equal(-1, Integer.test_unpack("\xFF"*2, 2, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal(-1, Integer.test_unpack("\xFF"*3, 3, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal(-1, Integer.test_unpack("\xFF"*4, 4, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal(-1, Integer.test_unpack("\xFF"*5, 5, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal(-1, Integer.test_unpack("\xFF"*6, 6, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal(-1, Integer.test_unpack("\xFF"*7, 7, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal(-1, Integer.test_unpack("\xFF"*8, 8, 1, 0, TWOCOMP|BIG_ENDIAN)) + assert_equal(-1, Integer.test_unpack("\xFF"*9, 9, 1, 0, TWOCOMP|BIG_ENDIAN)) + end + + def test_unpack2comp_negative_single_byte + assert_equal(-256, Integer.test_unpack("\x00", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE)) + assert_equal(-255, Integer.test_unpack("\x01", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE)) + assert_equal(-254, Integer.test_unpack("\x02", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE)) + assert_equal(-129, Integer.test_unpack("\x7F", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE)) + assert_equal(-128, Integer.test_unpack("\x80", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE)) + assert_equal( -2, Integer.test_unpack("\xFE", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE)) + assert_equal( -1, Integer.test_unpack("\xFF", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE)) + end + + def test_unpack2comp_negative_zero + 0.upto(100) {|n| + str = "\x00"*n + flags = TWOCOMP|BIG_ENDIAN|NEGATIVE + assert_equal(-(256**n), Integer.test_unpack(str, n, 1, 0, flags)) + flags = TWOCOMP|LITTLE_ENDIAN|NEGATIVE + assert_equal(-(256**n), Integer.test_unpack(str, n, 1, 0, flags), + "Integer.test_unpack(#{str.dump}, #{n}, 1, 0, #{'%#x' % flags})") + } + end + end + + def test_numbits_2comp + assert_equal(4, -9.test_numbits_2comp_without_sign) + assert_equal(3, -8.test_numbits_2comp_without_sign) + assert_equal(3, -7.test_numbits_2comp_without_sign) + assert_equal(3, -6.test_numbits_2comp_without_sign) + assert_equal(3, -5.test_numbits_2comp_without_sign) + assert_equal(2, -4.test_numbits_2comp_without_sign) + assert_equal(2, -3.test_numbits_2comp_without_sign) + assert_equal(1, -2.test_numbits_2comp_without_sign) + assert_equal(0, -1.test_numbits_2comp_without_sign) + assert_equal(0, 0.test_numbits_2comp_without_sign) + assert_equal(1, 1.test_numbits_2comp_without_sign) + assert_equal(2, 2.test_numbits_2comp_without_sign) + assert_equal(2, 3.test_numbits_2comp_without_sign) + assert_equal(3, 4.test_numbits_2comp_without_sign) + assert_equal(3, 5.test_numbits_2comp_without_sign) + assert_equal(3, 6.test_numbits_2comp_without_sign) + assert_equal(3, 7.test_numbits_2comp_without_sign) + assert_equal(4, 8.test_numbits_2comp_without_sign) + assert_equal(4, 9.test_numbits_2comp_without_sign) + end + + def test_numbytes_2comp + assert_equal(6, -0x8000000001.test_numbytes_2comp_with_sign) + assert_equal(5, -0x8000000000.test_numbytes_2comp_with_sign) + assert_equal(5, -0x80000001.test_numbytes_2comp_with_sign) + assert_equal(4, -0x80000000.test_numbytes_2comp_with_sign) + assert_equal(4, -0x800001.test_numbytes_2comp_with_sign) + assert_equal(3, -0x800000.test_numbytes_2comp_with_sign) + assert_equal(3, -0x8001.test_numbytes_2comp_with_sign) + assert_equal(2, -0x8000.test_numbytes_2comp_with_sign) + assert_equal(2, -0x81.test_numbytes_2comp_with_sign) + assert_equal(1, -0x80.test_numbytes_2comp_with_sign) + assert_equal(1, -1.test_numbytes_2comp_with_sign) + assert_equal(1, 0.test_numbytes_2comp_with_sign) + assert_equal(1, 1.test_numbytes_2comp_with_sign) + assert_equal(1, 0x7f.test_numbytes_2comp_with_sign) + assert_equal(2, 0x80.test_numbytes_2comp_with_sign) + assert_equal(2, 0x7fff.test_numbytes_2comp_with_sign) + assert_equal(3, 0x8000.test_numbytes_2comp_with_sign) + assert_equal(3, 0x7fffff.test_numbytes_2comp_with_sign) + assert_equal(4, 0x800000.test_numbytes_2comp_with_sign) + assert_equal(4, 0x7fffffff.test_numbytes_2comp_with_sign) + assert_equal(5, 0x80000000.test_numbytes_2comp_with_sign) + assert_equal(5, 0x7fffffffff.test_numbytes_2comp_with_sign) + assert_equal(6, 0x8000000000.test_numbytes_2comp_with_sign) + end + +end diff --git a/jni/ruby/test/-ext-/bignum/test_str2big.rb b/jni/ruby/test/-ext-/bignum/test_str2big.rb new file mode 100644 index 0000000..4304be8 --- /dev/null +++ b/jni/ruby/test/-ext-/bignum/test_str2big.rb @@ -0,0 +1,37 @@ +require 'test/unit' +require "-test-/bignum" + +class TestBignum < Test::Unit::TestCase + class TestStr2big < Test::Unit::TestCase + + SIZEOF_BDIGIT = Bignum::SIZEOF_BDIGIT + BITSPERDIG = Bignum::BITSPERDIG + BDIGMAX = (1 << BITSPERDIG) - 1 + + def test_str2big_poweroftwo + s = "1" + "0" * 1000 + n = 16 ** 1000 + assert_equal(n, s.str2big_poweroftwo(16, true)) + end + + def test_str2big_normal + s = "1" + "0" * 1000 + n = 10 ** 1000 + assert_equal(n, s.str2big_normal(10, true)) + end + + def test_str2big_karatsuba + s = "1" + "0" * 1000 + n = 10 ** 1000 + assert_equal(n, s.str2big_karatsuba(10, true)) + end + + def test_str2big_gmp + s = "1" + "0" * 1000 + n = 10 ** 1000 + assert_equal(n, s.str2big_gmp(10, true)) + rescue NotImplementedError + end + + end +end diff --git a/jni/ruby/test/-ext-/bug_reporter/test_bug_reporter.rb b/jni/ruby/test/-ext-/bug_reporter/test_bug_reporter.rb new file mode 100644 index 0000000..6ac5b8f --- /dev/null +++ b/jni/ruby/test/-ext-/bug_reporter/test_bug_reporter.rb @@ -0,0 +1,25 @@ +require 'test/unit' +require 'tmpdir' + +class TestBugReporter < Test::Unit::TestCase + def test_bug_reporter_add + expected_stderr = [ + :*, + /\[BUG\]\sSegmentation\sfault.*\n/, + /#{ Regexp.quote(RUBY_DESCRIPTION) }\n\n/, + :*, + /Sample bug reporter: 12345/, + :* + ] + tmpdir = Dir.mktmpdir + + args = ["--disable-gems", "-r-test-/bug_reporter/bug_reporter", + "-C", tmpdir] + stdin = "register_sample_bug_reporter(12345); Process.kill :SEGV, $$" + _, stderr, status = EnvUtil.invoke_ruby(args, stdin, false, true) + stderr.force_encoding("ASCII-8BIT") + assert_pattern_list(expected_stderr, stderr) + ensure + FileUtils.rm_rf(tmpdir) if tmpdir + end +end diff --git a/jni/ruby/test/-ext-/class/test_class2name.rb b/jni/ruby/test/-ext-/class/test_class2name.rb new file mode 100644 index 0000000..070be5a --- /dev/null +++ b/jni/ruby/test/-ext-/class/test_class2name.rb @@ -0,0 +1,18 @@ +require 'test/unit' +require "-test-/class" + +class Test_Class < Test::Unit::TestCase + class Test_Class2Name < superclass + def test_toplevel_class + assert_equal("Object", Bug::Class.class2name(::Object)) + end + + def test_toplevel_module + assert_equal("Kernel", Bug::Class.class2name(::Kernel)) + end + + def test_singleton_class + assert_equal("Object", Bug::Class.class2name(::Object.new.singleton_class)) + end + end +end diff --git a/jni/ruby/test/-ext-/debug/test_debug.rb b/jni/ruby/test/-ext-/debug/test_debug.rb new file mode 100644 index 0000000..ec506e0 --- /dev/null +++ b/jni/ruby/test/-ext-/debug/test_debug.rb @@ -0,0 +1,58 @@ +require 'test/unit' +require '-test-/debug' + +class TestDebug < Test::Unit::TestCase + + def binds_check(binds, msg = nil) + count = Hash.new(0) + assert_instance_of(Array, binds, msg) + binds.each{|(_self, bind, klass, iseq, loc)| + if _self == self + count[:self] += 1 + end + + if bind + assert_instance_of(Binding, bind, msg) + count[:bind] += 1 + end + + if klass + assert(klass.instance_of?(Module) || klass.instance_of?(Class), msg) + count[:class] += 1 + end + + if iseq + count[:iseq] += 1 + assert_instance_of(RubyVM::InstructionSequence, iseq, msg) + + # check same location + assert_equal(loc.path, iseq.path, msg) + assert_equal(loc.absolute_path, iseq.absolute_path, msg) + assert_equal(loc.label, iseq.label, msg) + assert_operator(loc.lineno, :>=, iseq.first_lineno, msg) + end + + assert_instance_of(Thread::Backtrace::Location, loc, msg) + + } + assert_operator(0, :<, count[:self], msg) + assert_operator(0, :<, count[:bind], msg) + assert_operator(0, :<, count[:iseq], msg) + assert_operator(0, :<, count[:class], msg) + end + + def test_inspector_open + binds = Bug::Debug.inspector + binds_check binds + end + + def inspector_in_eval + eval("Bug::Debug.inspector") + end + + def test_inspector_open_in_eval + bug7635 = '[ruby-core:51640]' + binds = inspector_in_eval + binds_check binds, bug7635 + end +end diff --git a/jni/ruby/test/-ext-/debug/test_profile_frames.rb b/jni/ruby/test/-ext-/debug/test_profile_frames.rb new file mode 100644 index 0000000..1879c22 --- /dev/null +++ b/jni/ruby/test/-ext-/debug/test_profile_frames.rb @@ -0,0 +1,104 @@ +require 'test/unit' +require '-test-/debug' + +class SampleClassForTestProfileFrames + class Sample2 + def baz(block) + instance_eval "def zab(block) block.call end" + [self, zab(block)] + end + end + + def self.bar(block) + Sample2.new.baz(block) + end + + def foo(block) + self.class.bar(block) + end +end + +class TestProfileFrames < Test::Unit::TestCase + def test_profile_frames + obj, frames = Fiber.new{ + Fiber.yield SampleClassForTestProfileFrames.new.foo(lambda{ Bug::Debug.profile_frames(0, 10) }) + }.resume + + labels = [ + "block (2 levels) in test_profile_frames", + "zab", + "baz", + "bar", + "foo", + "block in test_profile_frames", + ] + base_labels = [ + "test_profile_frames", + "zab", + "baz", + "bar", + "foo", + "test_profile_frames", + ] + full_labels = [ + "block (2 levels) in TestProfileFrames#test_profile_frames", + "#{obj.inspect}.zab", + "SampleClassForTestProfileFrames::Sample2#baz", + "SampleClassForTestProfileFrames.bar", + "SampleClassForTestProfileFrames#foo", + "block in TestProfileFrames#test_profile_frames", + ] + classes = [ + TestProfileFrames, + obj, + SampleClassForTestProfileFrames::Sample2, + SampleClassForTestProfileFrames, # singleton method + SampleClassForTestProfileFrames, + TestProfileFrames, + ] + singleton_method_p = [ + false, true, false, true, false, false, false, + ] + method_names = [ + "test_profile_frames", + "zab", + "baz", + "bar", + "foo", + "test_profile_frames", + ] + qualified_method_names = [ + "TestProfileFrames#test_profile_frames", + "#{obj.inspect}.zab", + "SampleClassForTestProfileFrames::Sample2#baz", + "SampleClassForTestProfileFrames.bar", + "SampleClassForTestProfileFrames#foo", + "TestProfileFrames#test_profile_frames", + ] + paths = [ file=__FILE__, "(eval)", file, file, file, file ] + absolute_paths = [ file, nil, file, file, file, file ] + + # pp frames + + assert_equal(labels.size, frames.size) + + frames.each.with_index{|(path, absolute_path, label, base_label, full_label, first_lineno, + classpath, singleton_p, method_name, qualified_method_name), i| + err_msg = "#{i}th frame" + assert_equal(paths[i], path, err_msg) + assert_equal(absolute_paths[i], absolute_path, err_msg) + assert_equal(labels[i], label, err_msg) + assert_equal(base_labels[i], base_label, err_msg) + assert_equal(singleton_method_p[i], singleton_p, err_msg) + assert_equal(method_names[i], method_name, err_msg) + assert_match(qualified_method_names[i], qualified_method_name, err_msg) + assert_match(full_labels[i], full_label, err_msg) + assert_match(classes[i].inspect, classpath, err_msg) + if label == method_name + c = classes[i] + m = singleton_p ? c.method(method_name) : c.instance_method(method_name) + assert_equal(m.source_location[1], first_lineno, err_msg) + end + } + end +end diff --git a/jni/ruby/test/-ext-/exception/test_data_error.rb b/jni/ruby/test/-ext-/exception/test_data_error.rb new file mode 100644 index 0000000..53cbb28 --- /dev/null +++ b/jni/ruby/test/-ext-/exception/test_data_error.rb @@ -0,0 +1,13 @@ +require 'test/unit' + +module Bug + class TestException < Test::Unit::TestCase + def test_cleanup_data_error + bug9167 = '[ruby-core:58643] [Bug #9167]' + assert_normal_exit(<<-'end;', bug9167) # do + require '-test-/exception' + raise Bug::Exception::DataError, "Error" + end; + end + end +end diff --git a/jni/ruby/test/-ext-/exception/test_enc_raise.rb b/jni/ruby/test/-ext-/exception/test_enc_raise.rb new file mode 100644 index 0000000..a578b16 --- /dev/null +++ b/jni/ruby/test/-ext-/exception/test_enc_raise.rb @@ -0,0 +1,15 @@ +require 'test/unit' +require '-test-/exception' + +module Bug + class TestException < Test::Unit::TestCase + def test_enc_raise + feature5650 = '[ruby-core:41160]' + Encoding.list.each do |enc| + next unless enc.ascii_compatible? + e = assert_raise(Bug::Exception) {Bug::Exception.enc_raise(enc, "[Feature #5650]")} + assert_equal(enc, e.message.encoding, feature5650) + end + end + end +end diff --git a/jni/ruby/test/-ext-/exception/test_ensured.rb b/jni/ruby/test/-ext-/exception/test_ensured.rb new file mode 100644 index 0000000..97d9794 --- /dev/null +++ b/jni/ruby/test/-ext-/exception/test_ensured.rb @@ -0,0 +1,31 @@ +require 'test/unit' + +module Bug + class Bug7802 < RuntimeError + end + + class TestException < Test::Unit::TestCase + def test_ensured + assert_separately([], <<-'end;') # do + + require '-test-/exception' + + module Bug + class Bug7802 < RuntimeError + def try_method + raise self + end + + def ensured_method + [1].detect {|i| true} + end + end + end + + assert_raise(Bug::Bug7802, '[ruby-core:52022] [Bug #7802]') { + Bug::Exception.ensured(Bug::Bug7802.new) + } + end; + end + end +end diff --git a/jni/ruby/test/-ext-/file/test_stat.rb b/jni/ruby/test/-ext-/file/test_stat.rb new file mode 100644 index 0000000..b9aa132 --- /dev/null +++ b/jni/ruby/test/-ext-/file/test_stat.rb @@ -0,0 +1,14 @@ +require 'test/unit' +require "-test-/file" + +class Test_FileStat < Test::Unit::TestCase + def test_stat_for_fd + st = open(__FILE__) {|f| Bug::File::Stat.for_fd(f.fileno)} + assert_equal(File.stat(__FILE__), st) + end + + def test_stat_for_path + st = Bug::File::Stat.for_path(__FILE__) + assert_equal(File.stat(__FILE__), st) + end +end diff --git a/jni/ruby/test/-ext-/float/test_nextafter.rb b/jni/ruby/test/-ext-/float/test_nextafter.rb new file mode 100644 index 0000000..e3a3e72 --- /dev/null +++ b/jni/ruby/test/-ext-/float/test_nextafter.rb @@ -0,0 +1,57 @@ +require 'test/unit' +require "-test-/float" + +class TestFloatExt < Test::Unit::TestCase + NEXTAFTER_VALUES = [ + -Float::INFINITY, + -Float::MAX, + -100.0, + -1.0-Float::EPSILON, + -1.0, + -Float::EPSILON, + -Float::MIN/2, + -Math.ldexp(0.5, Float::MIN_EXP - Float::MANT_DIG + 1), + -0.0, + 0.0, + Math.ldexp(0.5, Float::MIN_EXP - Float::MANT_DIG + 1), + Float::MIN/2, + Float::MIN, + Float::EPSILON, + 1.0, + 1.0+Float::EPSILON, + 100.0, + Float::MAX, + Float::INFINITY, + Float::NAN + ] + + test_number = 0 + NEXTAFTER_VALUES.each {|n1| + NEXTAFTER_VALUES.each {|n2| + tag = n2.infinite? ? "ruby" : "other" + test_name = "test_nextafter_#{test_number}_#{tag}_#{n1}_#{n2}" + test_number += 1 + define_method(test_name) { + v1 = Bug::Float.missing_nextafter(n1, n2) + v2 = Bug::Float.system_nextafter(n1, n2) + assert_kind_of(Float, v1) + assert_kind_of(Float, v2) + if v1.nan? + assert(v2.nan?, "Bug::Float.system_nextafter(#{n1}, #{n2}).nan?") + else + assert_equal(v1, v2, + "Bug::Float.missing_nextafter(#{'%a' % n1}, #{'%a' % n2}) = #{'%a' % v1} != " + + "#{'%a' % v2} = Bug::Float.system_nextafter(#{'%a' % n1}, #{'%a' % n2})") + if v1 == 0 + s1 = 1.0/v1 < 0 ? "negative-zero" : "positive-zero" + s2 = 1.0/v2 < 0 ? "negative-zero" : "positive-zero" + assert_equal(s1, s2, + "Bug::Float.missing_nextafter(#{'%a' % n1}, #{'%a' % n2}) = #{'%a' % v1} != " + + "#{'%a' % v2} = Bug::Float.system_nextafter(#{'%a' % n1}, #{'%a' % n2})") + end + end + } + } + } + +end diff --git a/jni/ruby/test/-ext-/funcall/test_passing_block.rb b/jni/ruby/test/-ext-/funcall/test_passing_block.rb new file mode 100644 index 0000000..87aed22 --- /dev/null +++ b/jni/ruby/test/-ext-/funcall/test_passing_block.rb @@ -0,0 +1,22 @@ +require 'test/unit' + +class TestFuncall < Test::Unit::TestCase + module Relay + def self.target(*args, &block) + yield(*args) if block + end + end + require '-test-/funcall/funcall' + + def test_with_funcall2 + ok = nil + Relay.with_funcall2("feature#4504") {|arg| ok = arg || true} + assert_nil(ok) + end + + def test_with_funcall_passing_block + ok = nil + Relay.with_funcall_passing_block("feature#4504") {|arg| ok = arg || true} + assert_equal("feature#4504", ok) + end +end diff --git a/jni/ruby/test/-ext-/hash/test_delete.rb b/jni/ruby/test/-ext-/hash/test_delete.rb new file mode 100644 index 0000000..13f3595 --- /dev/null +++ b/jni/ruby/test/-ext-/hash/test_delete.rb @@ -0,0 +1,19 @@ +require 'test/unit' +require '-test-/hash' + +class TestHash < Test::Unit::TestCase + class TestDelete < Test::Unit::TestCase + def test_delete + hash = Bug::Hash.new + hash[1] = 2 + called = false + assert_equal 1, hash.size + assert_equal [2], hash.delete!(1) {called = true} + assert_equal false, called, "block called" + assert_equal 0, hash.size + assert_equal nil, hash.delete!(1) {called = true} + assert_equal false, called, "block called" + assert_equal 0, hash.size + end + end +end diff --git a/jni/ruby/test/-ext-/iseq_load/test_iseq_load.rb b/jni/ruby/test/-ext-/iseq_load/test_iseq_load.rb new file mode 100644 index 0000000..5bbd49e --- /dev/null +++ b/jni/ruby/test/-ext-/iseq_load/test_iseq_load.rb @@ -0,0 +1,95 @@ +require 'test/unit' + +class TestIseqLoad < Test::Unit::TestCase + require '-test-/iseq_load/iseq_load' + ISeq = RubyVM::InstructionSequence + + def test_bug8543 + assert_iseq_roundtrip <<-'end;' + puts "tralivali" + def funct(a, b) + a**b + end + 3.times { |i| puts "Hello, world#{funct(2,i)}!" } + end; + end + + def test_case_when + assert_iseq_roundtrip <<-'end;' + def user_mask(target) + target.each_char.inject(0) do |mask, chr| + case chr + when "u" + mask | 04700 + when "g" + mask | 02070 + when "o" + mask | 01007 + when "a" + mask | 07777 + else + raise ArgumentError, "invalid `who' symbol in file mode: #{chr}" + end + end + end + end; + end + + def test_splatsplat + assert_iseq_roundtrip('def splatsplat(**); end') + end + + def test_hidden + assert_iseq_roundtrip('def x(a, (b, *c), d: false); end') + end + + def assert_iseq_roundtrip(src) + a = ISeq.compile(src).to_a + b = ISeq.iseq_load(a).to_a + warn diff(a, b) if a != b + assert_equal a, b + assert_equal a, ISeq.iseq_load(b).to_a + end + + def test_next_in_block_in_block + skip "failing due to stack_max mismatch" + assert_iseq_roundtrip <<-'end;' + 3.times { 3.times { next } } + end; + end + + def test_break_ensure + skip "failing due to exception entry sp mismatch" + assert_iseq_roundtrip <<-'end;' + def m + bad = true + while true + begin + break + ensure + bad = false + end + end + end + end; + end + + # FIXME: still failing + def test_require_integration + skip "iseq loader require integration tests still failing" + f = File.expand_path(__FILE__) + # $(top_srcdir)/test/ruby/test_....rb + 3.times { f = File.dirname(f) } + Dir[File.join(f, 'ruby', '*.rb')].each do |f| + iseq = ISeq.compile_file(f) + orig = iseq.to_a.freeze + + loaded = ISeq.iseq_load(orig).to_a + if loaded != orig + warn f + warn diff(orig, loaded) + end + #assert_equal orig, loaded + end + end +end diff --git a/jni/ruby/test/-ext-/iter/test_iter_break.rb b/jni/ruby/test/-ext-/iter/test_iter_break.rb new file mode 100644 index 0000000..5bac633 --- /dev/null +++ b/jni/ruby/test/-ext-/iter/test_iter_break.rb @@ -0,0 +1,15 @@ +require 'test/unit' +require '-test-/iter' + +module TestIter +end + +class TestIter::IterBreak < Test::Unit::TestCase + def test_iter_break + backport7896 = '[ruby-core:52607]' + assert_equal(nil, 1.times{Bug::Iter::Breakable.iter_break}, backport7896) + + feature5895 = '[ruby-dev:45132]' + assert_equal(42, 1.times{Bug::Iter::Breakable.iter_break_value(42)}, feature5895) + end +end diff --git a/jni/ruby/test/-ext-/iter/test_yield_block.rb b/jni/ruby/test/-ext-/iter/test_yield_block.rb new file mode 100644 index 0000000..bec993c --- /dev/null +++ b/jni/ruby/test/-ext-/iter/test_yield_block.rb @@ -0,0 +1,21 @@ +require 'test/unit' +require '-test-/iter' + +module TestIter +end + +class TestIter::YieldBlock < Test::Unit::TestCase + class YieldTest + include Bug::Iter::Yield + attr_reader :blockarg + def test(arg, &block) + block.call(arg) {|blockarg| @blockarg = blockarg} + end + end + + def test_yield_block + a = YieldTest.new + a.yield_block(:test, "foo") {|x, &b| assert_kind_of(Proc, b); b.call(x)} + assert_equal("foo", a.blockarg) + end +end diff --git a/jni/ruby/test/-ext-/load/test_dot_dot.rb b/jni/ruby/test/-ext-/load/test_dot_dot.rb new file mode 100644 index 0000000..82aa10a --- /dev/null +++ b/jni/ruby/test/-ext-/load/test_dot_dot.rb @@ -0,0 +1,10 @@ +require 'test/unit' + +class Test_DotDot < Test::Unit::TestCase + def test_load_dot_dot + feature = '[ruby-dev:41774]' + assert_nothing_raised(LoadError, feature) { + require '-test-/load/dot.dot/dot.dot' + } + end +end diff --git a/jni/ruby/test/-ext-/marshal/test_usrmarshal.rb b/jni/ruby/test/-ext-/marshal/test_usrmarshal.rb new file mode 100644 index 0000000..8d8db01 --- /dev/null +++ b/jni/ruby/test/-ext-/marshal/test_usrmarshal.rb @@ -0,0 +1,32 @@ +require 'test/unit' +require '-test-/marshal/usr' + +module Bug end + +module Bug::Marshal + class TestUsrMarshal < Test::Unit::TestCase + def old_dump + @old_dump ||= + begin + src = "module Bug; module Marshal; class UsrMarshal; def initialize(val) @value = val; end; end; ::Marshal.dump(UsrMarshal.new(42), STDOUT); end; end" + EnvUtil.invoke_ruby([], src, true)[0] + end + end + + def test_marshal + v = ::Marshal.load(::Marshal.dump(UsrMarshal.new(42))) + assert_instance_of(UsrMarshal, v) + assert_equal(42, v.value) + end + + def test_incompat + assert_raise_with_message(ArgumentError, "dump format error") {::Marshal.load(old_dump)} + end + + def test_compat + out, err = EnvUtil.invoke_ruby(["-r-test-/marshal/usr", "-r-test-/marshal/compat", "-e", "::Marshal.dump(::Marshal.load(STDIN), STDOUT)"], old_dump, true, true) + assert_equal(::Marshal.dump(UsrMarshal.new(42)), out) + assert_equal("", err) + end + end +end diff --git a/jni/ruby/test/-ext-/method/test_arity.rb b/jni/ruby/test/-ext-/method/test_arity.rb new file mode 100644 index 0000000..79ef23b --- /dev/null +++ b/jni/ruby/test/-ext-/method/test_arity.rb @@ -0,0 +1,37 @@ +require '-test-/method' +require 'test/unit' + +class TestMethod < Test::Unit::TestCase + class TestArity < Test::Unit::TestCase + class A + def foo0() + end + def foom1(*a) + end + def foom2(a,*b) + end + def foo1(a) + end + def foo2(a,b) + end + end + + class B<A + private :foo1, :foo2 + end + + METHODS = {foo0: 0, foo1: 1, foo2: 2, foom1: -1, foom2: -2} + + def test_base + METHODS.each do |name, arity| + assert_equal(arity, Bug::Method.mod_method_arity(A, name), "A##{name}") + end + end + + def test_zsuper + METHODS.each do |name, arity| + assert_equal(arity, Bug::Method.mod_method_arity(B, name), "B##{name}") + end + end + end +end diff --git a/jni/ruby/test/-ext-/num2int/test_num2int.rb b/jni/ruby/test/-ext-/num2int/test_num2int.rb new file mode 100644 index 0000000..f579659 --- /dev/null +++ b/jni/ruby/test/-ext-/num2int/test_num2int.rb @@ -0,0 +1,267 @@ +require 'test/unit' +require '-test-/num2int/num2int' + +class TestNum2int < Test::Unit::TestCase + SHRT_MIN = -32768 + SHRT_MAX = 32767 + USHRT_MAX = 65535 + + INT_MIN = -2147483648 + INT_MAX = 2147483647 + UINT_MAX = 4294967295 + + case [0].pack('L!').size + when 4 + LONG_MAX = 2147483647 + LONG_MIN = -2147483648 + ULONG_MAX = 4294967295 + when 8 + LONG_MAX = 9223372036854775807 + LONG_MIN = -9223372036854775808 + ULONG_MAX = 18446744073709551615 + end + + LLONG_MAX = 9223372036854775807 + LLONG_MIN = -9223372036854775808 + ULLONG_MAX = 18446744073709551615 + + FIXNUM_MAX = LONG_MAX/2 + FIXNUM_MIN = LONG_MIN/2 + + def fix2big(n) + 10000000000000000000000000000.coerce(n)[0] + end + + def assert_num2i_success_internal(exp, func, arg) + mesg = "#{func}(#{arg.inspect})" + out = nil + assert_nothing_raised(mesg) { + out = Num2int.send(func, arg) + } + assert_equal(exp, out, mesg) + end + + def assert_num2i_success(type, num, result=num) + func = "NUM2#{type}".upcase + assert_num2i_success_internal(result.to_s, func, num) + assert_num2i_success_internal(result.to_s, func, fix2big(num)) + assert_num2i_success_internal(result.to_s, func, Rational(num, 1)) + if num.to_f.to_i == num + assert_num2i_success_internal(result.to_s, func, num.to_f) + end + # The conversion functions such as NUM2INT uses (conceptually) to_int. + if (arg = num.to_f + 0.5) != num.to_f && arg.to_int == num + assert_num2i_success_internal(result.to_s, func, arg) + end + if (arg = num.to_f - 0.5) != num.to_f && arg.to_int == num + assert_num2i_success_internal(result.to_s, func, arg) + end + if (arg = num + Rational(1,2)) && arg.to_int == num + assert_num2i_success_internal(result.to_s, func, arg) + end + if (arg = num - Rational(1,2)) && arg.to_int == num + assert_num2i_success_internal(result.to_s, func, arg) + end + end + + def assert_num2i_error_internal(func, arg) + assert_raise(RangeError, "#{func}(#{arg.inspect})") { + Num2int.send(func, arg) + } + end + + def assert_num2i_error(type, num) + func = "NUM2#{type}".upcase + assert_num2i_error_internal(func, num) + assert_num2i_error_internal(func, fix2big(num)) + assert_num2i_error_internal(func, Rational(num, 1)) + if num.to_f.to_i == num + assert_num2i_error_internal(func, num.to_f) + end + # The conversion functions such as NUM2INT uses (conceptually) to_int. + if (arg = num.to_f + 0.5) != num.to_f && arg.to_int == num + assert_num2i_error_internal(func, arg) + end + if (arg = num.to_f - 0.5) != num.to_f && arg.to_int == num + assert_num2i_error_internal(func, arg) + end + if (arg = num + Rational(1,2)) && arg.to_int == num + assert_num2i_error_internal(func, arg) + end + if (arg = num - Rational(1,2)) && arg.to_int == num + assert_num2i_error_internal(func, arg) + end + end + + def assert_fix2i_success_internal(exp, func, arg) + mesg = "#{func}(#{arg.inspect})" + out = nil + assert_nothing_raised(mesg) { + out = Num2int.send(func, arg) + } + assert_equal(exp, out, mesg) + end + + def assert_fix2i_success(type, num, result=num) + return if !num.kind_of?(Fixnum) + func = "FIX2#{type}".upcase + assert_fix2i_success_internal(result.to_s, func, num) + end + + def assert_fix2i_error_internal(func, arg) + assert_raise(RangeError, "#{func}(#{arg.inspect})") { + Num2int.send(func, arg) + } + end + + def assert_fix2i_error(type, num) + return if !num.kind_of?(Fixnum) + func = "FIX2#{type}".upcase + assert_num2i_error_internal(func, num) + end + + def test_num2short + assert_num2i_success(:short, SHRT_MIN) + assert_num2i_success(:short, SHRT_MIN+1) + assert_num2i_success(:short, SHRT_MAX) + assert_num2i_error(:short, SHRT_MIN-1) + assert_num2i_error(:short, SHRT_MAX+1) + end + + def test_num2ushort + assert_num2i_success(:ushort, 0) + assert_num2i_success(:ushort, USHRT_MAX) + assert_num2i_success(:ushort, -1, USHRT_MAX) + assert_num2i_success(:ushort, SHRT_MIN, SHRT_MAX+1) + assert_num2i_success(:ushort, SHRT_MIN+1, SHRT_MAX+2) + assert_num2i_error(:ushort, SHRT_MIN-1) + assert_num2i_error(:ushort, USHRT_MAX+1) + end + + def test_num2int + assert_num2i_success(:int, INT_MIN) + assert_num2i_success(:int, INT_MIN+1) + assert_num2i_success(:int, INT_MAX) + assert_num2i_error(:int, INT_MIN-1) + assert_num2i_error(:int, INT_MAX+1) + end + + def test_num2uint + assert_num2i_success(:uint, 0) + assert_num2i_success(:uint, UINT_MAX) + assert_num2i_success(:uint, -1, UINT_MAX) + assert_num2i_success(:uint, INT_MIN, INT_MAX+1) + assert_num2i_success(:uint, INT_MIN+1, INT_MAX+2) + assert_num2i_error(:uint, INT_MIN-1) + assert_num2i_error(:uint, UINT_MAX+1) + end + + def test_num2long + assert_num2i_success(:long, LONG_MIN) + assert_num2i_success(:long, LONG_MIN+1) + assert_num2i_success(:long, LONG_MAX) + assert_num2i_error(:long, LONG_MIN-1) + assert_num2i_error(:long, LONG_MAX+1) + assert_num2i_success(:long, FIXNUM_MIN) + assert_num2i_success(:long, FIXNUM_MIN+1) + assert_num2i_success(:long, FIXNUM_MIN-1) + assert_num2i_success(:long, FIXNUM_MAX) + assert_num2i_success(:long, FIXNUM_MAX+1) + end + + def test_num2ulong + assert_num2i_success(:ulong, 0) + assert_num2i_success(:ulong, ULONG_MAX) + assert_num2i_success(:ulong, -1, ULONG_MAX) + assert_num2i_success(:ulong, LONG_MIN, LONG_MAX+1) + assert_num2i_success(:ulong, LONG_MIN+1, LONG_MAX+2) + assert_num2i_error(:ulong, LONG_MIN-1) + assert_num2i_error(:ulong, ULONG_MAX+1) + assert_num2i_success(:ulong, FIXNUM_MIN, ULONG_MAX-FIXNUM_MAX) + assert_num2i_success(:ulong, FIXNUM_MIN+1, ULONG_MAX-FIXNUM_MAX+1) + assert_num2i_success(:ulong, FIXNUM_MIN-1, ULONG_MAX-FIXNUM_MAX-1) + assert_num2i_success(:ulong, FIXNUM_MAX, FIXNUM_MAX) + assert_num2i_success(:ulong, FIXNUM_MAX+1, FIXNUM_MAX+1) + end + + def test_num2ll + assert_num2i_success(:ll, LLONG_MIN) + assert_num2i_success(:ll, LLONG_MIN+1) + assert_num2i_success(:ll, LLONG_MAX) + assert_num2i_error(:ll, LLONG_MIN-1) + assert_num2i_error(:ll, LLONG_MAX+1) + assert_num2i_success(:ll, FIXNUM_MIN) + assert_num2i_success(:ll, FIXNUM_MIN+1) + assert_num2i_success(:ll, FIXNUM_MIN-1) + assert_num2i_success(:ll, FIXNUM_MAX) + assert_num2i_success(:ll, FIXNUM_MAX+1) + end if defined?(Num2int.NUM2LL) + + def test_num2ull + assert_num2i_success(:ull, 0) + assert_num2i_success(:ull, ULLONG_MAX) + assert_num2i_success(:ull, -1, ULLONG_MAX) + assert_num2i_success(:ull, LLONG_MIN, LLONG_MAX+1) + assert_num2i_success(:ull, LLONG_MIN+1, LLONG_MAX+2) + assert_num2i_error(:ull, LLONG_MIN-1) + assert_num2i_error(:ull, ULLONG_MAX+1) + assert_num2i_success(:ull, FIXNUM_MIN, ULLONG_MAX-FIXNUM_MAX) + assert_num2i_success(:ull, FIXNUM_MIN+1, ULLONG_MAX-FIXNUM_MAX+1) + assert_num2i_success(:ull, FIXNUM_MIN-1, ULLONG_MAX-FIXNUM_MAX-1) + assert_num2i_success(:ull, FIXNUM_MAX) + assert_num2i_success(:ull, FIXNUM_MAX+1) + end if defined?(Num2int.NUM2ULL) + + def test_fix2short + assert_fix2i_success(:short, 0) + assert_fix2i_success(:short, SHRT_MAX) + assert_fix2i_success(:short, SHRT_MIN) + assert_fix2i_success(:short, SHRT_MIN+1) + assert_fix2i_error(:short, SHRT_MAX+1) + assert_fix2i_error(:short, SHRT_MIN-1) + assert_fix2i_error(:short, FIXNUM_MAX) + assert_fix2i_error(:short, FIXNUM_MIN) + assert_fix2i_error(:short, FIXNUM_MIN+1) + end + + def test_fix2int + assert_fix2i_success(:int, 0) + assert_fix2i_success(:int, INT_MAX) + assert_fix2i_success(:int, INT_MIN) + assert_fix2i_success(:int, INT_MIN+1) + assert_fix2i_error(:int, INT_MAX+1) + assert_fix2i_error(:int, INT_MIN-1) + assert_fix2i_error(:int, FIXNUM_MAX) if INT_MAX < FIXNUM_MAX + assert_fix2i_error(:int, FIXNUM_MIN) if FIXNUM_MIN < INT_MIN + assert_fix2i_error(:int, FIXNUM_MIN+1) if FIXNUM_MIN+1 < INT_MIN + end + + def test_fix2uint + assert_fix2i_success(:uint, 0) + assert_fix2i_success(:uint, UINT_MAX) + assert_fix2i_success(:uint, INT_MAX) + assert_fix2i_success(:uint, INT_MIN, INT_MAX+1) + assert_fix2i_success(:uint, INT_MIN+1, INT_MAX+2) + assert_fix2i_error(:uint, UINT_MAX+1) + assert_fix2i_error(:uint, INT_MIN-1) + assert_fix2i_error(:uint, FIXNUM_MAX) if UINT_MAX < FIXNUM_MAX + assert_fix2i_error(:uint, FIXNUM_MIN) if FIXNUM_MIN < INT_MIN + assert_fix2i_error(:uint, FIXNUM_MIN+1) if FIXNUM_MIN+1 < INT_MIN + end + + def test_fix2long + assert_fix2i_success(:long, 0) + assert_fix2i_success(:long, FIXNUM_MAX) + assert_fix2i_success(:long, FIXNUM_MIN) + assert_fix2i_success(:long, FIXNUM_MIN+1) + end + + def test_fix2ulong + assert_fix2i_success(:ulong, 0) + assert_fix2i_success(:ulong, FIXNUM_MAX) + assert_fix2i_success(:ulong, -1, ULONG_MAX) + end + +end + + diff --git a/jni/ruby/test/-ext-/path_to_class/test_path_to_class.rb b/jni/ruby/test/-ext-/path_to_class/test_path_to_class.rb new file mode 100644 index 0000000..fdf4097 --- /dev/null +++ b/jni/ruby/test/-ext-/path_to_class/test_path_to_class.rb @@ -0,0 +1,12 @@ +require 'test/unit' + +class Test_PathToClass < Test::Unit::TestCase + require '-test-/path_to_class/path_to_class' + + def test_path_to_class + bug5691 = '[ruby-core:41410]' + assert_raise(ArgumentError, bug5691) { + Test_PathToClass.path_to_class("Test_PathToClass::Object") + } + end +end diff --git a/jni/ruby/test/-ext-/postponed_job/test_postponed_job.rb b/jni/ruby/test/-ext-/postponed_job/test_postponed_job.rb new file mode 100644 index 0000000..032e35c --- /dev/null +++ b/jni/ruby/test/-ext-/postponed_job/test_postponed_job.rb @@ -0,0 +1,28 @@ +require 'test/unit' +require 'thread' +require '-test-/postponed_job' + +module Bug + def self.postponed_job_call_direct_wrapper(*args) + postponed_job_call_direct(*args) + end + + def self.postponed_job_register_wrapper(*args) + postponed_job_register(*args) + end +end + +class TestPostponed_job < Test::Unit::TestCase + def test_register + direct, registered = [], [] + + Bug.postponed_job_call_direct_wrapper(direct) + Bug.postponed_job_register_wrapper(registered) + + assert_match( /postponed_job_call_direct_wrapper/, direct.join) + assert_not_match( /postponed_job_register_wrapper/, registered.join) + + Bug.postponed_job_register_one(ary = []) + assert_equal [1], ary + end +end diff --git a/jni/ruby/test/-ext-/proc/test_bmethod.rb b/jni/ruby/test/-ext-/proc/test_bmethod.rb new file mode 100644 index 0000000..16927dc --- /dev/null +++ b/jni/ruby/test/-ext-/proc/test_bmethod.rb @@ -0,0 +1,37 @@ +require 'test/unit' +require '-test-/proc' + +class TestProc < Test::Unit::TestCase + class TestBMethod < Test::Unit::TestCase + end +end + +class TestProc::TestBMethod + class Base + def foo(*a) + a + end + end + + class Bound < Base + define_method(:foo, Bug::Proc.make_call_super(42)) + define_method(:receiver, Bug::Proc.make_call_receiver(nil)) + end + + def test_super_in_bmethod + obj = Bound.new + assert_equal([1, 42], obj.foo(1)) + end + + def test_block_super + obj = Bound.new + result = nil + obj.foo(2) {|*a| result = a} + assert_equal([2, 42], result) + end + + def test_receiver_in_bmethod + obj = Bound.new + assert_same(obj, obj.receiver) + end +end diff --git a/jni/ruby/test/-ext-/rational/test_rat.rb b/jni/ruby/test/-ext-/rational/test_rat.rb new file mode 100644 index 0000000..ef7e7fe --- /dev/null +++ b/jni/ruby/test/-ext-/rational/test_rat.rb @@ -0,0 +1,31 @@ +require 'test/unit' +require "-test-/rational" + +class TestRational < Test::Unit::TestCase + class TestGCD < Test::Unit::TestCase + + def test_gcd_normal + x = 2*2*3*3*3 + y = 2*2*2*3*3 + gcd = 2*2*3*3 + assert_equal(gcd, x.gcd_normal(y)) + end + + def test_gcd_gmp + x = 2*2*3*3*3 + y = 2*2*2*3*3 + gcd = 2*2*3*3 + assert_equal(gcd, x.gcd_gmp(y)) + rescue NotImplementedError + end + + def test_gcd_gmp_brute_force + -13.upto(13) {|x| + -13.upto(13) {|y| + assert_equal(x.gcd_normal(y), x.gcd_gmp(y)) + } + } + rescue NotImplementedError + end + end +end diff --git a/jni/ruby/test/-ext-/st/test_foreach.rb b/jni/ruby/test/-ext-/st/test_foreach.rb new file mode 100644 index 0000000..259b0a9 --- /dev/null +++ b/jni/ruby/test/-ext-/st/test_foreach.rb @@ -0,0 +1,15 @@ +require 'test/unit' +require '-test-/st/foreach' + +class Test_StForeachUnpack < Test::Unit::TestCase + def test_st_foreach_check_unpack + assert_nil Bug.unp_st_foreach_check(:check), "goto unpacked_continue" + assert_nil Bug.unp_st_foreach_check(:delete1), "goto unpacked" + assert_nil Bug.unp_st_foreach_check(:delete2), "goto deleted" + end + + def test_st_foreach_unpack + assert_nil Bug.unp_st_foreach(:unpacked), "goto unpacked" + assert_nil Bug.unp_st_foreach(:unpack_delete), "if (!ptr) return 0" + end +end diff --git a/jni/ruby/test/-ext-/st/test_numhash.rb b/jni/ruby/test/-ext-/st/test_numhash.rb new file mode 100644 index 0000000..24dc87c --- /dev/null +++ b/jni/ruby/test/-ext-/st/test_numhash.rb @@ -0,0 +1,49 @@ +require 'test/unit' +require "-test-/st/numhash" + +class Bug::StNumHash + class Test_NumHash < Test::Unit::TestCase + def setup + @tbl = Bug::StNumHash.new + 5.times {|i| @tbl[i] = i} + end + + def test_check + keys = [] + @tbl.each do |k, v, t| + keys << k + t[5] = 5 if k == 3 + true + end + assert_equal([*0..5], keys) + end + + def test_update + assert_equal(true, @tbl.update(0) {@tbl[5] = :x}) + assert_equal(:x, @tbl[0]) + assert_equal(:x, @tbl[5]) + end + + def test_size_after_delete_safe + 10.downto(1) do |up| + tbl = Bug::StNumHash.new + 1.upto(up){|i| tbl[i] = i} + assert_equal(1, tbl.delete_safe(1)) + assert_equal(up - 1, tbl.size, "delete_safe doesn't change size from #{up} to #{up-1}") + end + end + + def test_delete_safe_on_iteration + 10.downto(1) do |up| + tbl = Bug::StNumHash.new + 1.upto(up){|i| tbl[i] = i} + assert_nothing_raised("delete_safe forces iteration to fail with size #{up}") do + tbl.each do |k, v, t| + assert_equal k, t.delete_safe(k) + true + end + end + end + end + end +end diff --git a/jni/ruby/test/-ext-/st/test_update.rb b/jni/ruby/test/-ext-/st/test_update.rb new file mode 100644 index 0000000..1b41d2b --- /dev/null +++ b/jni/ruby/test/-ext-/st/test_update.rb @@ -0,0 +1,50 @@ +require 'test/unit' +require "-test-/st/update" + +class Bug::StTable + class Test_Update < Test::Unit::TestCase + def setup + @tbl = Bug::StTable.new + @tbl[:a] = 1 + @tbl[:b] = 2 + end + + def test_notfound + assert_equal(false, @tbl.st_update(:c) {42}) + assert_equal({a: 1, b: 2, c: 42}, @tbl) + end + + def test_continue + args = nil + assert_equal(true, @tbl.st_update(:a) {|*x| args = x; false}) + assert_equal({a: 1, b: 2}, @tbl, :a) + assert_equal([:a, 1], args) + end + + def test_delete + args = nil + assert_equal(true, @tbl.st_update(:a) {|*x| args = x; nil}) + assert_equal({b: 2}, @tbl, :a) + assert_equal([:a, 1], args) + end + + def test_update + args = nil + assert_equal(true, @tbl.st_update(:a) {|*x| args = x; 3}) + assert_equal({a: 3, b: 2}, @tbl, :a) + assert_equal([:a, 1], args) + end + + def test_pass_objects_in_st_table + bug7330 = '[ruby-core:49220]' + key = "abc".freeze + value = "def" + @tbl[key] = value + @tbl.st_update("abc") {|*args| + assert_same(key, args[0], bug7330) + assert_same(value, args[1], bug7330) + nil + } + end + end +end diff --git a/jni/ruby/test/-ext-/string/test_coderange.rb b/jni/ruby/test/-ext-/string/test_coderange.rb new file mode 100644 index 0000000..83cebf1 --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_coderange.rb @@ -0,0 +1,59 @@ +# coding: ascii-8bit +require 'test/unit' +require "-test-/string/string" +require "rbconfig/sizeof" + +class Test_StringCoderange < Test::Unit::TestCase + def setup + @sizeof_voidp = RbConfig::SIZEOF["void*"] + @a8 = Encoding::ASCII_8BIT + @a7 = Encoding::US_ASCII + @u8 = Encoding::UTF_8 + end + + def test_ascii8bit + enc = @a8 + str = "a" + str.force_encoding(enc) + assert_equal :"7bit", Bug::String.new(str).coderange_scan + + str = "a\xBE".force_encoding(enc) + assert_equal :valid, Bug::String.new(str).coderange_scan + end + + def test_usascii + enc = @a7 + str = "a" + str.force_encoding(enc) + assert_equal :"7bit", Bug::String.new(str).coderange_scan + + str = "a" * (@sizeof_voidp * 2) + str << "\xBE" + str.force_encoding(enc) + assert_equal :broken, Bug::String.new(str).coderange_scan + end + + def test_utf8 + enc = @u8 + str = "a" + str.force_encoding(enc) + assert_equal :"7bit", Bug::String.new(str).coderange_scan + + str = "a" * (@sizeof_voidp * 3) + str << "aa\xC2\x80" + str.force_encoding(enc) + assert_equal :valid, Bug::String.new(str).coderange_scan + + str = "a" * (@sizeof_voidp * 2) + str << "\xC2\x80" + str << "a" * (@sizeof_voidp * 2) + str.force_encoding(enc) + assert_equal :valid, Bug::String.new(str).coderange_scan + + str = "a" * (@sizeof_voidp * 2) + str << "\xC1\x80" + str << "a" * (@sizeof_voidp * 2) + str.force_encoding(enc) + assert_equal :broken, Bug::String.new(str).coderange_scan + end +end diff --git a/jni/ruby/test/-ext-/string/test_cstr.rb b/jni/ruby/test/-ext-/string/test_cstr.rb new file mode 100644 index 0000000..272e090 --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_cstr.rb @@ -0,0 +1,119 @@ +require 'test/unit' +require "-test-/string/string" + +class Test_StringCStr < Test::Unit::TestCase + Bug4319 = '[ruby-dev:43094]' + + def test_embed + s = Bug::String.new("abcdef") + s.set_len(3) + assert_equal(0, s.cstr_term, Bug4319) + end + + def test_long + s = Bug::String.new("abcdef")*100000 + assert_equal(0, s.cstr_term, Bug4319) + end + + WCHARS = [Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE] + + def test_wchar_embed + WCHARS.each do |enc| + s = Bug::String.new("\u{4022}a".encode(enc)) + assert_nothing_raised(ArgumentError) {s.cstr_term} + s.set_len(s.bytesize / 2) + assert_equal(1, s.size) + assert_equal(0, s.cstr_term) + end + end + + def test_wchar_long + str = "\u{4022}abcdef" + n = 100 + len = str.size * n + WCHARS.each do |enc| + s = Bug::String.new(str.encode(enc))*n + assert_nothing_raised(ArgumentError, enc.name) {s.cstr_term} + s.set_len(s.bytesize / 2) + assert_equal(len / 2, s.size, enc.name) + assert_equal(0, s.cstr_term, enc.name) + end + end + + def test_wchar_lstrip! + assert_wchars_term_char(" a") {|s| s.lstrip!} + end + + def test_wchar_rstrip! + assert_wchars_term_char("a ") {|s| s.rstrip!} + end + + def test_wchar_chop! + assert_wchars_term_char("a\n") {|s| s.chop!} + end + + def test_wchar_chomp! + assert_wchars_term_char("a\n") {|s| s.chomp!} + end + + def test_wchar_aset + assert_wchars_term_char("a"*30) {|s| s[29,1] = ""} + end + + def test_wchar_sub! + assert_wchars_term_char("foobar") {|s| s.sub!(/#{"foo".encode(s.encoding)}/, "")} + end + + def test_wchar_delete! + assert_wchars_term_char("foobar") {|s| s.delete!("ao".encode(s.encoding))} + end + + def test_wchar_squeeze! + assert_wchars_term_char("foo!") {|s| s.squeeze!} + end + + def test_wchar_tr! + assert_wchars_term_char("\u{3042}foobar") {|s| + enc = s.encoding + s.tr!("\u{3042}".encode(enc), "c".encode(enc)) + } + end + + def test_wchar_tr_s! + assert_wchars_term_char("\u{3042}foobar") {|s| + enc = s.encoding + s.tr_s!("\u{3042}".encode(enc), "c".encode(enc)) + } + end + + def test_embedded_from_heap + gh821 = "[GH-821]" + embedded_string = "abcdefghi" + string = embedded_string.gsub("efg", "123") + {}[string] = 1 + non_terminated = "#{string}#{nil}" + assert_nil(Bug::String.cstr_term_char(non_terminated), gh821) + + result = {} + WCHARS.map do |enc| + embedded_string = "ab".encode(enc) + string = embedded_string.gsub("b".encode(enc), "1".encode(enc)) + {}[string] = 1 + non_terminated = "#{string}#{nil}" + c = Bug::String.cstr_term_char(non_terminated) + result[enc] = c if c + end + assert_empty(result, gh821) + end + + def assert_wchars_term_char(str) + result = {} + WCHARS.map do |enc| + s = Bug::String.new(str.encode(enc)) + yield s + c = s.cstr_term_char + result[enc] = c if c + end + assert_empty(result) + end +end diff --git a/jni/ruby/test/-ext-/string/test_ellipsize.rb b/jni/ruby/test/-ext-/string/test_ellipsize.rb new file mode 100644 index 0000000..2c14c0c --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_ellipsize.rb @@ -0,0 +1,46 @@ +require 'test/unit' +require "-test-/string/string" + +class Test_StringEllipsize < Test::Unit::TestCase + def setup + @foobar = Bug::String.new("foobar") + end + + def assert_equal_with_class(expected, result, *rest) + assert_equal(expected.encoding, result.encoding, *rest) + assert_equal(expected, result, result.encoding.name) + assert_instance_of(Bug::String, result, *rest) + end + + def test_longer + assert_equal_with_class("", @foobar.ellipsize(0)) + assert_equal_with_class(".", @foobar.ellipsize(1)) + assert_equal_with_class("..", @foobar.ellipsize(2)) + assert_equal_with_class("...", @foobar.ellipsize(3)) + assert_equal_with_class("f...", @foobar.ellipsize(4)) + assert_equal_with_class("fo...", @foobar.ellipsize(5)) + end + + def test_shorter + assert_same(@foobar, @foobar.ellipsize(6)) + assert_same(@foobar, @foobar.ellipsize(7)) + end + + def test_negative_length + assert_raise(IndexError) {@foobar.ellipsize(-1)} + end + + def test_nonascii + a = "\u3042" + Encoding.list.each do |enc| + next if enc.dummy? + begin + s = a.encode(enc) + e = "...".encode(enc) + rescue + else + assert_equal_with_class(s*12+e, Bug::String.new(s*20).ellipsize(15)) + end + end + end +end diff --git a/jni/ruby/test/-ext-/string/test_enc_associate.rb b/jni/ruby/test/-ext-/string/test_enc_associate.rb new file mode 100644 index 0000000..edddfb4 --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_enc_associate.rb @@ -0,0 +1,12 @@ +require 'test/unit' +require "-test-/string/string" + +class Test_StrEncAssociate < Test::Unit::TestCase + def test_frozen + s = Bug::String.new("abc") + s.force_encoding(Encoding::US_ASCII) + s.freeze + assert_raise(RuntimeError) {s.associate_encoding!(Encoding::US_ASCII)} + assert_raise(RuntimeError) {s.associate_encoding!(Encoding::UTF_8)} + end +end diff --git a/jni/ruby/test/-ext-/string/test_enc_str_buf_cat.rb b/jni/ruby/test/-ext-/string/test_enc_str_buf_cat.rb new file mode 100644 index 0000000..9582fe2 --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_enc_str_buf_cat.rb @@ -0,0 +1,15 @@ +require 'test/unit' +require "-test-/string/string" + +class Test_StringEncStrBufCat < Test::Unit::TestCase + Bug6509 = '[ruby-dev:45688]' + + def test_unknown + a8_str = "a\xBE".force_encoding(Encoding::ASCII_8BIT) + cr_unknown_str = [0x62].pack('C*') + assert_equal(true, a8_str.valid_encoding?, "an assertion for following tests") + assert_equal(:valid, Bug::String.new(a8_str).coderange, "an assertion for following tests") + assert_equal(:unknown, Bug::String.new(cr_unknown_str).coderange, "an assertion for following tests") + assert_equal(:valid, Bug::String.new(a8_str).enc_str_buf_cat(cr_unknown_str).coderange, Bug6509) + end +end diff --git a/jni/ruby/test/-ext-/string/test_modify_expand.rb b/jni/ruby/test/-ext-/string/test_modify_expand.rb new file mode 100644 index 0000000..34b7be7 --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_modify_expand.rb @@ -0,0 +1,15 @@ +require 'test/unit' +require "-test-/string/string" + +class Test_StringModifyExpand < Test::Unit::TestCase + def test_modify_expand_memory_leak + assert_no_memory_leak(["-r-test-/string/string"], + <<-PRE, <<-CMD, "rb_str_modify_expand()", limit: 2.5) + s=Bug::String.new + PRE + size = $initial_size + 10.times{s.modify_expand!(size)} + s.replace("") + CMD + end +end diff --git a/jni/ruby/test/-ext-/string/test_nofree.rb b/jni/ruby/test/-ext-/string/test_nofree.rb new file mode 100644 index 0000000..234c84d --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_nofree.rb @@ -0,0 +1,10 @@ +require 'test/unit' + +class Test_StringNoFree < Test::Unit::TestCase + def test_no_memory_leak + bug10942 = '[ruby-core:68436] [Bug #10942] no leak on nofree string' + assert_no_memory_leak(%w(-r-test-/string/string), '', + '1000000.times {Bug::String.nofree << "a" * 100}', + bug10942, rss: true, limit: 2.0) + end +end diff --git a/jni/ruby/test/-ext-/string/test_normalize.rb b/jni/ruby/test/-ext-/string/test_normalize.rb new file mode 100644 index 0000000..283ca93 --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_normalize.rb @@ -0,0 +1,106 @@ +require 'test/unit' +require "-test-/string/string" +require "tempfile" + +class Test_StringNormalize < Test::Unit::TestCase +=begin + def test_normalize_all + exclude = [ + #0x340, 0x341, 0x343, 0x344 + ] + (0x0080..0xFFFD).each do |n| + next if 0xD800 <= n && n <= 0xDFFF + next if exclude.include? n + code = n.to_s(16) + Tempfile.create("#{code}-#{n.chr(Encoding::UTF_8)}-") do |tempfile| + ary = Dir.glob(File.expand_path("../#{code}-*", tempfile.path)) + assert_equal 1, ary.size + result = ary[0] + rn = result[/\/\h+-(.+?)-/, 1] + #assert_equal tempfile.path, result, "#{rn.dump} is not U+#{n.to_s(16)}" + r2 = Bug::String.new(result ).normalize_ospath + rn2 = r2[/\/\h+-(.+?)-/, 1] + if tempfile.path == result + if tempfile.path == r2 + else + puts "U+#{n.to_s(16)} shouldn't be r2#{rn2.dump}" + end + else + if tempfile.path == r2 + # puts "U+#{n.to_s(16)} shouldn't be r#{rn.dump}" + elsif result == r2 + puts "U+#{n.to_s(16)} shouldn't be #{rn.dump}" + else + puts "U+#{n.to_s(16)} shouldn't be r#{rn.dump} r2#{rn2.dump}" + end + end + end + end + end +=end + + def test_normalize + %[ + \u304C \u304B\u3099 + \u3077 \u3075\u309A + \u308F\u3099 \u308F\u3099 + \u30F4 \u30A6\u3099 + \u30DD \u30DB\u309A + \u30AB\u303A \u30AB\u303A + \u00C1 A\u0301 + B\u030A B\u030A + \u0386 \u0391\u0301 + \u03D3 \u03D2\u0301 + \u0401 \u0415\u0308 + \u2260 =\u0338 + \u{c548} \u{110b}\u{1161}\u{11ab} + ].scan(/(\S+)\s+(\S+)/) do |expected, src| + result = Bug::String.new(src).normalize_ospath + assert_equal expected, result, + "#{expected.dump} is expected but #{src.dump}" + end + rescue NotImplementedError + end + + def test_not_normalize_kc + %[ + \u2460 + \u2162 + \u3349 + \u33A1 + \u337B + \u2116 + \u33CD + \u2121 + \u32A4 + \u3231 + ].split.each do |src| + result = Bug::String.new(src).normalize_ospath + assert_equal src, result, + "#{src.dump} is expected not to be normalized, but #{result.dump}" + end + rescue NotImplementedError + end + + def test_dont_normalize_hfsplus + %[ + \u2190\u0338 + \u219A + \u212B + \uF90A + \uF9F4 + \uF961 \uF9DB + \uF96F \uF3AA + \uF915 \uF95C \uF9BF + \uFA0C + \uFA10 + \uFA19 + \uFA26 + ].split.each do |src| + result = Bug::String.new(src).normalize_ospath + assert_equal src, result, + "#{src.dump} is expected not to be normalized, but #{result.dump}" + end + rescue NotImplementedError + end +end diff --git a/jni/ruby/test/-ext-/string/test_qsort.rb b/jni/ruby/test/-ext-/string/test_qsort.rb new file mode 100644 index 0000000..3a58523 --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_qsort.rb @@ -0,0 +1,19 @@ +require 'test/unit' +require "-test-/string/string" + +class Test_StringQSort < Test::Unit::TestCase + def test_qsort + s = Bug::String.new("xxozfxx") + s.qsort! + assert_equal("foxxxxz", s) + end + + def test_qsort_slice + s = Bug::String.new("xxofzx1") + s.qsort!(nil, nil, 3) + assert_equal("fzxxxo1", s) + s = Bug::String.new("xxofzx231") + s.qsort!(nil, nil, 3) + assert_equal("231fzxxxo", s) + end +end diff --git a/jni/ruby/test/-ext-/string/test_set_len.rb b/jni/ruby/test/-ext-/string/test_set_len.rb new file mode 100644 index 0000000..e257cac --- /dev/null +++ b/jni/ruby/test/-ext-/string/test_set_len.rb @@ -0,0 +1,25 @@ +require 'test/unit' +require "-test-/string/string" + +class Test_StrSetLen < Test::Unit::TestCase + def setup + @s0 = [*"a".."z"].join("").freeze + @s1 = Bug::String.new(@s0) + end + + def teardown + orig = [*"a".."z"].join("") + assert_equal(orig, @s0) + end + + def test_non_shared + @s1.modify! + assert_equal("abc", @s1.set_len(3)) + end + + def test_shared + assert_raise(RuntimeError) { + assert_equal("abc", @s1.set_len(3)) + } + end +end diff --git a/jni/ruby/test/-ext-/struct/test_member.rb b/jni/ruby/test/-ext-/struct/test_member.rb new file mode 100644 index 0000000..18e9808 --- /dev/null +++ b/jni/ruby/test/-ext-/struct/test_member.rb @@ -0,0 +1,15 @@ +require 'test/unit' +require "-test-/struct" + +class Bug::Struct::Test_Member < Test::Unit::TestCase + S = Bug::Struct.new(:a) + + def test_member_get + s = S.new(1) + assert_equal(1, s.get(:a)) + assert_raise_with_message(NameError, /is not a struct member/) {s.get(:b)} + EnvUtil.with_default_external(Encoding::UTF_8) do + assert_raise_with_message(NameError, /\u{3042}/) {s.get(:"\u{3042}")} + end + end +end diff --git a/jni/ruby/test/-ext-/symbol/test_inadvertent_creation.rb b/jni/ruby/test/-ext-/symbol/test_inadvertent_creation.rb new file mode 100644 index 0000000..f772086 --- /dev/null +++ b/jni/ruby/test/-ext-/symbol/test_inadvertent_creation.rb @@ -0,0 +1,473 @@ +require 'test/unit' +require "-test-/symbol" + +module Test_Symbol + class TestInadvertent < Test::Unit::TestCase + def noninterned_name(prefix = "") + prefix += "_#{Thread.current.object_id.to_s(36).tr('-', '_')}" + begin + name = "#{prefix}_#{rand(0x1000).to_s(16)}_#{Time.now.usec}" + end while Bug::Symbol.find(name) + name + end + + def setup + @obj = Object.new + end + + def assert_not_pinneddown(name, msg = nil) + assert_not_send([Bug::Symbol, :pinneddown?, name], msg) + end + + def assert_not_interned(name, msg = nil) + assert_not_send([Bug::Symbol, :find, name], msg) + end + + def assert_not_interned_error(obj, meth, name, msg = nil, &block) + e = assert_raise(NameError, msg) {obj.__send__(meth, name, &block)} + if Symbol === name + assert_not_pinneddown(name, msg) + else + assert_not_interned(name, msg) + end + e + end + + def assert_not_interned_false(obj, meth, name, msg = nil) + assert_not_send([obj, meth, name], msg) + if Symbol === name + assert_not_pinneddown(name, msg) + else + assert_not_interned(name, msg) + end + end + + Feature5072 = '[ruby-core:38367]' + + def test_module_const_get + cl = Class.new + name = noninterned_name("A") + + assert_not_interned_error(cl, :const_get, name, Feature5072) + + assert_not_interned_error(cl, :const_get, name.to_sym) + end + + def test_module_const_defined? + cl = Class.new + name = noninterned_name("A") + + assert_not_interned_false(cl, :const_defined?, name, Feature5072) + + name = noninterned_name + assert_not_interned_error(cl, :const_defined?, name.to_sym) + end + + def test_respond_to_missing + feature5072 = Feature5072 + c = Class.new do + def self.respond_to_missing?(*) + super + end + end + s = noninterned_name + + # assert_not_interned_false(c, :respond_to?, s, feature5072) + assert_not_interned_false(c, :method_defined?, s, feature5072) + assert_not_interned_false(c, :public_method_defined?, s, feature5072) + assert_not_interned_false(c, :private_method_defined?, s, feature5072) + assert_not_interned_false(c, :protected_method_defined?, s, feature5072) + assert_not_interned_false(c, :const_defined?, noninterned_name("A"), feature5072) + assert_not_interned_false(c, :instance_variable_defined?, noninterned_name("@"), feature5072) + assert_not_interned_false(c, :class_variable_defined?, noninterned_name("@@"), feature5072) + end + + def test_missing_method + bug10985 = '[ruby-core:68564] [Bug #10985]' + m = nil + c = Class.new do + def self.respond_to_missing?(*) + true + end + end + + s = noninterned_name + assert_nothing_raised(NameError, bug10985) {m = c.method(s)} + assert_raise_with_message(NoMethodError, /#{s}/) {m.call} + + s = noninterned_name + assert_nothing_raised(NameError, bug10985) {m = c.public_method(s.to_sym)} + assert_raise_with_message(NoMethodError, /#{s}/) {m.call} + + s = noninterned_name + assert_nothing_raised(NameError, bug10985) {m = c.singleton_method(s.to_sym)} + assert_raise_with_message(NoMethodError, /#{s}/) {m.call} + end + + Feature5079 = '[ruby-core:38404]' + + def test_undefined_instance_variable + feature5079 = feature5079 + c = Class.new + iv = noninterned_name("@") + + assert_not_interned_false(c, :instance_variable_get, iv, feature5079) + assert_not_interned_error(c, :remove_instance_variable, iv, feature5079) + end + + def test_undefined_class_variable + feature5079 = feature5079 + c = Class.new + cv = noninterned_name("@@") + + assert_not_interned_error(c, :class_variable_get, cv, feature5079) + assert_not_interned_error(c, :remove_class_variable, cv, feature5079) + end + + + def test_undefined_const + feature5079 = feature5079 + c = Class.new + s = noninterned_name("A") + + assert_not_interned_error(c, :remove_const, s, feature5079) + end + + def test_undefined_method + feature5079 = feature5079 + c = Class.new + s = noninterned_name + + assert_not_interned_error(c, :method, s, feature5079) + assert_not_interned_error(c, :public_method, s, feature5079) + assert_not_interned_error(c, :instance_method, s, feature5079) + assert_not_interned_error(c, :public_instance_method, s, feature5079) + end + + Feature5089 = '[ruby-core:38447]' + def test_const_missing + feature5089 = Feature5089 + c = Class.new do + def self.const_missing(const_name) + raise NameError, const_name.to_s + end + end + s = noninterned_name("A") + + assert_not_interned_error(c, :const_get, s.to_sym, feature5089) + assert_not_interned_false(c, :autoload?, s.to_sym, feature5089) + end + + def test_aliased_method + feature5089 = Feature5089 + c = Class.new do + def self.alias_method(str) + super(:puts, str) + end + end + s = noninterned_name + + assert_not_interned_error(c, :alias_method, s, feature5089) + assert_not_interned_error(c, :private_class_method, s, feature5089) + assert_not_interned_error(c, :private_constant, s, feature5089) + assert_not_interned_error(c, :private, s, feature5089) + assert_not_interned_error(c, :protected, s, feature5089) + assert_not_interned_error(c, :public, s, feature5089) + assert_not_interned_error(c, :public_class_method, s, feature5089) + assert_not_interned_error(c, :public_constant, s, feature5089) + assert_not_interned_error(c, :remove_method, s, feature5089) + assert_not_interned_error(c, :undef_method, s, feature5089) + assert_not_interned_error(c, :untrace_var, s, feature5089) + end + + Feature5112 = '[ruby-core:38576]' + + def test_public_send + name = noninterned_name + e = assert_raise(NoMethodError) {@obj.public_send(name, Feature5112)} + assert_not_interned(name) + assert_equal(name, e.name) + assert_equal([Feature5112], e.args) + end + + def test_send + name = noninterned_name + e = assert_raise(NoMethodError) {@obj.send(name, Feature5112)} + assert_not_interned(name) + assert_equal(name, e.name) + assert_equal([Feature5112], e.args) + end + + def test___send__ + name = noninterned_name + e = assert_raise(NoMethodError) {@obj.__send__(name, Feature5112)} + assert_not_interned(name) + assert_equal(name, e.name) + assert_equal([Feature5112], e.args) + end + + def test_thread_aref + Thread.current[:test] = nil + name = noninterned_name + assert_nil(Thread.current[name]) + assert_not_interned(name) + end + + def test_thread_key? + Thread.current[:test] = nil + name = noninterned_name + assert_not_send([Thread.current, :key?, name]) + assert_not_interned(name) + end + + def test_thread_variable_get + Thread.current.thread_variable_set(:test, nil) + name = noninterned_name + assert_nil(Thread.current.thread_variable_get(name)) + assert_not_pinneddown(name) + end + + def test_thread_variable_set + name = noninterned_name + Thread.current.thread_variable_set(name, 42) + assert_not_pinneddown(name) + end + + def test_thread_variable? + Thread.current.thread_variable_set(:test, nil) + name = noninterned_name + assert_not_send([Thread.current, :thread_variable?, name]) + assert_not_interned(name) + end + + def test_enumerable_inject_op + name = noninterned_name + assert_raise(NoMethodError) {[1, 2].inject(name)} + assert_not_interned(name) + end + + def test_module_const_set + name = noninterned_name + mod = Module.new + assert_raise(NameError) {mod.const_set(name, true)} + assert_not_interned(name) + assert_raise(NameError) {mod.const_set(name.to_sym, true)} + assert_not_pinneddown(name) + end + + def test_module_cvar_set + name = noninterned_name + mod = Module.new + assert_raise(NameError) {mod.class_variable_set(name, true)} + assert_not_interned(name) + assert_raise(NameError) {mod.class_variable_set(name.to_sym, true)} + assert_not_pinneddown(name) + end + + def test_object_ivar_set + name = noninterned_name + obj = Object.new + assert_raise(NameError) {obj.instance_variable_set(name, true)} + assert_not_interned(name) + assert_raise(NameError) {obj.instance_variable_set(name.to_sym, true)} + assert_not_pinneddown(name) + end + + def test_struct_new + name = noninterned_name + assert_raise(NameError) {Struct.new(name)} + assert_not_interned(name) + end + + def test_struct_aref + s = Struct.new(:foo).new + name = noninterned_name + assert_raise(NameError) {s[name]} + assert_not_interned(name) + end + + def test_struct_aset + s = Struct.new(:foo).new + name = noninterned_name + assert_raise(NameError) {s[name] = true} + assert_not_interned(name) + end + + def test_invalid_attr + name = noninterned_name("*") + mod = Module.new + assert_raise(NameError) {mod.module_eval {attr(name)}} + assert_not_interned(name) + assert_raise(NameError) {mod.module_eval {attr(name.to_sym)}} + assert_not_pinneddown(name) + end + + def test_invalid_attr_reader + name = noninterned_name("*") + mod = Module.new + assert_raise(NameError) {mod.module_eval {attr_reader(name)}} + assert_not_interned(name) + assert_raise(NameError) {mod.module_eval {attr_reader(name.to_sym)}} + assert_not_pinneddown(name) + end + + def test_invalid_attr_writer + name = noninterned_name("*") + mod = Module.new + assert_raise(NameError) {mod.module_eval {attr_writer(name)}} + assert_not_interned(name) + assert_raise(NameError) {mod.module_eval {attr_writer(name.to_sym)}} + assert_not_pinneddown(name) + end + + def test_invalid_attr_accessor + name = noninterned_name("*") + mod = Module.new + assert_raise(NameError) {mod.module_eval {attr_accessor(name)}} + assert_not_interned(name) + assert_raise(NameError) {mod.module_eval {attr_accessor(name.to_sym)}} + assert_not_pinneddown(name) + end + + def test_gc_attrset + assert_separately(['-r-test-/symbol', '-', '[ruby-core:62226] [Bug #9787]'], <<-'end;') # begin + bug = ARGV.shift + def noninterned_name(prefix = "") + prefix += "_#{Thread.current.object_id.to_s(36).tr('-', '_')}" + begin + name = "#{prefix}_#{rand(0x1000).to_s(16)}_#{Time.now.usec}" + end while Bug::Symbol.find(name) or Bug::Symbol.find(name + "=") + name + end + names = Array.new(1000) {noninterned_name("gc")} + names.each {|n| n.to_sym} + GC.start(immediate_sweep: false) + names.each do |n| + eval(":#{n}=") + assert_nothing_raised(TypeError, bug) {eval("proc{self.#{n} = nil}")} + end + end; + end + + def test_execopt_key + name = noninterned_name.intern + assert_raise(ArgumentError) { + system(".", name => nil) + } + assert_not_pinneddown(name) + end + + def test_execopt_redirect_value + name = noninterned_name.intern + assert_raise(ArgumentError) { + system(".", [] => name) + } + assert_not_pinneddown(name) + end + + def test_execopt_redirect_path + name = noninterned_name.intern + assert_raise(TypeError) { + system(".", [] => [name, 0]) + } + assert_not_pinneddown(name) + end + + def test_execopt_redirect_symbol + name = noninterned_name.intern + assert_raise(ArgumentError) { + system(".", in: name) + } + assert_not_pinneddown(name) + end + + def assert_no_immortal_symbol_created(name) + name = noninterned_name(name) + yield(name) + assert_not_pinneddown(name) + end + + def assert_no_immortal_symbol_in_method_missing(name) + assert_no_immortal_symbol_created("send should not leak - #{name}") do |name| + assert_raise(NoMethodError) {yield(name)} + end + end + + def test_send_leak_string + assert_no_immortal_symbol_in_method_missing("str") do |name| + 42.send(name) + end + end + + def test_send_leak_symbol + assert_no_immortal_symbol_in_method_missing("sym") do |name| + 42.send(name.to_sym) + end + end + + def test_send_leak_string_custom_method_missing + x = Object.new + def x.method_missing(*); super; end + assert_no_immortal_symbol_in_method_missing("str mm") do |name| + x.send(name) + end + end + + def test_send_leak_symbol_custom_method_missing + x = Object.new + def x.method_missing(*); super; end + assert_no_immortal_symbol_in_method_missing("sym mm") do |name| + x.send(name.to_sym) + end + end + + def test_send_leak_string_no_optimization + assert_no_immortal_symbol_in_method_missing("str slow") do |name| + 42.method(:send).call(name) + end + end + + def test_send_leak_symbol_no_optimization + assert_no_immortal_symbol_in_method_missing("sym slow") do |name| + 42.method(:send).call(name.to_sym) + end + end + + def test_send_leak_string_custom_method_missing_no_optimization + x = Object.new + def x.method_missing(*); super; end + assert_no_immortal_symbol_in_method_missing("str mm slow") do |name| + x.method(:send).call(name) + end + end + + def test_send_leak_symbol_custom_method_missing_no_optimization + x = Object.new + def x.method_missing(*); super; end + assert_no_immortal_symbol_in_method_missing("sym mm slow") do |name| + x.method(:send).call(name.to_sym) + end + end + + def test_kwarg_symbol_leak_no_rest + foo = -> (arg: 42) {} + assert_no_immortal_symbol_created("kwarg no rest") do |name| + assert_raise(ArgumentError) { foo.call(name.to_sym => 42) } + end + end + + def test_kwarg_symbol_leak_with_rest + foo = -> (arg: 2, **options) {} + assert_no_immortal_symbol_created("kwarg with rest") do |name| + foo.call(name.to_sym => 42) + end + end + + def test_kwarg_symbol_leak_just_rest + foo = -> (**options) {} + assert_no_immortal_symbol_created("kwarg just rest") do |name| + foo.call(name.to_sym => 42) + end + end + end +end diff --git a/jni/ruby/test/-ext-/symbol/test_type.rb b/jni/ruby/test/-ext-/symbol/test_type.rb new file mode 100644 index 0000000..f1749f5 --- /dev/null +++ b/jni/ruby/test/-ext-/symbol/test_type.rb @@ -0,0 +1,124 @@ +require 'test/unit' +require "-test-/symbol" + +module Test_Symbol + class TestType < Test::Unit::TestCase + def test_id2str_fstring_bug9171 + fstr = eval("# encoding: us-ascii + 'foobar'.freeze") + assert_same fstr, Bug::Symbol.id2str(:foobar) + + fstr = eval("# encoding: us-ascii + '>'.freeze") + assert_same fstr, Bug::Symbol.id2str(:>) + end + + def assert_symtype(sym, pred, msg = nil) + assert_send([Bug::Symbol, pred, sym], msg) + end + + def assert_not_symtype(sym, pred, msg = nil) + assert_not_send([Bug::Symbol, pred, sym], msg) + end + + def test_const + assert_symtype("Foo", :const?) + assert_not_symtype("F!", :const?) + assert_not_symtype("foo", :const?) + assert_not_symtype("@foo", :const?) + assert_not_symtype("@@foo", :const?) + assert_not_symtype("$foo", :const?) + assert_not_symtype("foo=", :const?) + assert_not_symtype("[foo]", :const?) + assert_not_symtype("xFoo", :const?) + end + + def test_local + assert_symtype("foo", :local?) + assert_symtype("fooBar", :local?) + assert_symtype("foo_bar", :local?) + assert_not_symtype("foo!", :local?) + assert_not_symtype("foo?", :local?) + assert_not_symtype("Foo", :local?) + assert_not_symtype("@foo", :local?) + assert_not_symtype("@@foo", :local?) + assert_not_symtype("$foo", :local?) + assert_not_symtype("foo=", :local?) + assert_not_symtype("[foo]", :local?) + end + + def test_global + assert_symtype("$foo", :global?) + assert_symtype("$$", :global?) + assert_not_symtype("$()", :global?) + assert_not_symtype("$", :global?) + assert_not_symtype("foo", :global?) + assert_not_symtype("Foo", :global?) + assert_not_symtype("@foo", :global?) + assert_not_symtype("@@foo", :global?) + assert_not_symtype("foo=", :global?) + assert_not_symtype("[foo]", :global?) + end + + def test_instance + assert_symtype("@foo", :instance?) + assert_not_symtype("@", :instance?) + assert_not_symtype("@1", :instance?) + assert_not_symtype("@@", :instance?) + assert_not_symtype("foo", :instance?) + assert_not_symtype("Foo", :instance?) + assert_not_symtype("@@foo", :instance?) + assert_not_symtype("$foo", :instance?) + assert_not_symtype("foo=", :instance?) + assert_not_symtype("[foo]", :instance?) + end + + def test_class + assert_symtype("@@foo", :class?) + assert_not_symtype("@@", :class?) + assert_not_symtype("@", :class?) + assert_not_symtype("@@1", :class?) + assert_not_symtype("foo", :class?) + assert_not_symtype("Foo", :class?) + assert_not_symtype("@foo", :class?) + assert_not_symtype("$foo", :class?) + assert_not_symtype("foo=", :class?) + assert_not_symtype("[foo]", :class?) + end + + def test_attrset + assert_symtype("foo=", :attrset?) + assert_symtype("Foo=", :attrset?) + assert_symtype("@foo=", :attrset?) + assert_symtype("@@foo=", :attrset?) + assert_symtype("$foo=", :attrset?) + assert_symtype("0=", :attrset?) + assert_symtype("@=", :attrset?) + assert_symtype("@@=", :attrset?) + assert_not_symtype("foo", :attrset?) + assert_not_symtype("Foo", :attrset?) + assert_not_symtype("@foo", :attrset?) + assert_not_symtype("@@foo", :attrset?) + assert_not_symtype("$foo", :attrset?) + assert_not_symtype("[foo]", :attrset?) + assert_symtype("[foo]=", :attrset?) + assert_equal(:"foo=", Bug::Symbol.attrset("foo")) + assert_symtype(Bug::Symbol.attrset("foo"), :attrset?) + assert_equal(:"Foo=", Bug::Symbol.attrset("Foo")) + assert_symtype(Bug::Symbol.attrset("Foo"), :attrset?) + assert_equal(:"@foo=", Bug::Symbol.attrset("@foo")) + assert_symtype(Bug::Symbol.attrset("@foo"), :attrset?) + assert_equal(:"@@foo=", Bug::Symbol.attrset("@@foo")) + assert_symtype(Bug::Symbol.attrset("@@foo"), :attrset?) + assert_equal(:"$foo=", Bug::Symbol.attrset("$foo")) + assert_symtype(Bug::Symbol.attrset("$foo"), :attrset?) + assert_equal(:"[foo]=", Bug::Symbol.attrset("[foo]")) + assert_symtype(Bug::Symbol.attrset("[foo]"), :attrset?) + assert_equal(:[]=, Bug::Symbol.attrset(:[])) + assert_symtype(Bug::Symbol.attrset("foo?="), :attrset?) + assert_equal(:"foo?=", Bug::Symbol.attrset(:foo?)) + assert_symtype(Bug::Symbol.attrset("foo!="), :attrset?) + assert_equal(:"foo!=", Bug::Symbol.attrset(:foo!)) + end + end +end diff --git a/jni/ruby/test/-ext-/test_bug-3571.rb b/jni/ruby/test/-ext-/test_bug-3571.rb new file mode 100644 index 0000000..d7c26d1 --- /dev/null +++ b/jni/ruby/test/-ext-/test_bug-3571.rb @@ -0,0 +1,20 @@ +require 'test/unit' + +class Test_BUG_3571 < Test::Unit::TestCase + def test_block_call_id + bug3571 = '[ruby-dev:41852]' + src = <<SRC +begin + Bug.start +rescue NotImplementedError => e + STDERR.puts e.message, e.backtrace[$0.size..-1] +end +SRC + out = [ + "start() function is unimplemented on this machine", + "-:2:in `start'", + "-:2:in `<main>'", + ] + assert_in_out_err(%w"-r-test-/bug-3571/bug", src, [], out, bug3571) + end +end diff --git a/jni/ruby/test/-ext-/test_bug-3662.rb b/jni/ruby/test/-ext-/test_bug-3662.rb new file mode 100644 index 0000000..73c0697 --- /dev/null +++ b/jni/ruby/test/-ext-/test_bug-3662.rb @@ -0,0 +1,10 @@ +require '-test-/bug-3662/bug' + +class Test_BUG_3662 < Test::Unit::TestCase + def test_funcall_notimplement + bug3662 = '[ruby-dev:41953]' + assert_raise(NotImplementedError, bug3662) { + Bug.funcall(:notimplement) + } + end +end diff --git a/jni/ruby/test/-ext-/test_bug-5832.rb b/jni/ruby/test/-ext-/test_bug-5832.rb new file mode 100644 index 0000000..11f8a52 --- /dev/null +++ b/jni/ruby/test/-ext-/test_bug-5832.rb @@ -0,0 +1,21 @@ +require '-test-/bug-5832/bug' + +class Test_BUG_5832 < Test::Unit::TestCase + def test_block_passing + bug5832 = '[ruby-dev:45071]' + + c = Class.new do + define_method(:call_invoke_block_from_c) do + Bug.funcall_callback(self) + end + + def callback + yield if block_given? + end + end + + assert_nothing_raised(RuntimeError, bug5832) do + c.new.call_invoke_block_from_c { raise 'unreachable' } + end + end +end diff --git a/jni/ruby/test/-ext-/test_printf.rb b/jni/ruby/test/-ext-/test_printf.rb new file mode 100644 index 0000000..1f06ad6 --- /dev/null +++ b/jni/ruby/test/-ext-/test_printf.rb @@ -0,0 +1,186 @@ +require 'test/unit' +require "-test-/printf" +require_relative '../ruby/allpairs' + +class Test_SPrintf < Test::Unit::TestCase + def to_s + "#{self.class}:#{object_id}" + end + + def inspect + "<#{self.class}:#{object_id}>" + end + + def test_to_str + assert_equal("<#{self.class}:#{object_id}>", Bug::Printf.s(self)) + end + + def test_inspect + assert_equal("{<#{self.class}:#{object_id}>}", Bug::Printf.v(self)) + end + + def test_quote + assert_equal('["\n"]', Bug::Printf.q("\n")) + assert_equal('[aaa]', Bug::Printf.q('aaa')) + assert_equal('[a a]', Bug::Printf.q('a a')) + end + + def test_encoding + def self.to_s + "\u{3042 3044 3046 3048 304a}" + end + assert_equal("<\u{3042 3044 3046 3048 304a}>", Bug::Printf.s(self)) + end + + def test_taint + obj = Object.new.taint + assert_equal({to_s: true, inspect: true}, + { + to_s: Bug::Printf.s(obj).tainted?, + inspect: Bug::Printf.v(obj).tainted?, + }) + end + + VS = [ + #-0x1000000000000000000000000000000000000000000000002, + #-0x1000000000000000000000000000000000000000000000001, + #-0x1000000000000000000000000000000000000000000000000, + #-0xffffffffffffffffffffffffffffffffffffffffffffffff, + #-0x1000000000000000000000002, + #-0x1000000000000000000000001, + #-0x1000000000000000000000000, + #-0xffffffffffffffffffffffff, + -0x10000000000000002, + -0x10000000000000001, + -0x10000000000000000, + -0xffffffffffffffff, + -0x4000000000000002, + -0x4000000000000001, + -0x4000000000000000, + -0x3fffffffffffffff, + -0x100000002, + -0x100000001, + -0x100000000, + -0xffffffff, + #-0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001 + -0x80000002, + -0x80000001, + -0x80000000, + -0x7fffffff, + #-0x524b2245, + -0x40000002, + -0x40000001, + -0x40000000, + -0x3fffffff, + #-0x10002, + #-0x10001, + #-0x10000, + #-0xffff, + #-0x8101, # 0x8101 * 0x7f01 = 0x40000001 + #-0x8002, + #-0x8001, + #-0x8000, + #-0x7fff, + #-0x7f01, + #-65, + #-64, + #-63, + #-62, + #-33, + #-32, + #-31, + #-30, + -3, + -2, + -1, + 0, + 1, + 2, + 3, + #30, + #31, + #32, + #33, + #62, + #63, + #64, + #65, + #0x7f01, + #0x7ffe, + #0x7fff, + #0x8000, + #0x8001, + #0x8101, + #0xfffe, + #0xffff, + #0x10000, + #0x10001, + 0x3ffffffe, + 0x3fffffff, + 0x40000000, + 0x40000001, + #0x524b2245, + 0x7ffffffe, + 0x7fffffff, + 0x80000000, + 0x80000001, + #0xc717a08d, + 0xfffffffe, + 0xffffffff, + 0x100000000, + 0x100000001, + 0x3ffffffffffffffe, + 0x3fffffffffffffff, + 0x4000000000000000, + 0x4000000000000001, + 0xfffffffffffffffe, + 0xffffffffffffffff, + 0x10000000000000000, + 0x10000000000000001, + #0xffffffffffffffffffffffff, + #0x1000000000000000000000000, + #0x1000000000000000000000001, + #0xffffffffffffffffffffffffffffffffffffffffffffffff, + #0x1000000000000000000000000000000000000000000000000, + #0x1000000000000000000000000000000000000000000000001 + ] + VS.reverse! + + FLAGS = [[nil, ' '], [nil, '#'], [nil, '+'], [nil, '-'], [nil, '0']] + + def self.assertions_format_integer(format, type, **opts) + proc { + VS.each {|v| + begin + r = Bug::Printf.(type, v, **opts) + rescue RangeError + else + e = sprintf format, v + assert_equal([e, format], r, "rb_sprintf(#{format.dump}, #{v})") + end + } + } + end + + AllPairs.each(%w[d], + # octal and hexadecimal deal with negative values differently + [nil, 0, 5, 20], + [nil, true, 0], # 8, 20 + *FLAGS) { + |type, width, prec, sp, hs, pl, mi, zr| + precision = ".#{prec unless prec == true}" if prec + format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}" + define_method("test_format_integer(#{format})", + assertions_format_integer(format, type, + space: sp, hash: hs, + plus: pl, minus: mi, + zero: zr, width: width, + prec: prec)) + } + + def test_string_prec + assert_equal("a", Bug::Printf.("s", "a", prec: 3)[0]) + assert_equal(" a", Bug::Printf.("s", "a", width: 3, prec: 3)[0]) + assert_equal("a ", Bug::Printf.("s", "a", minus: true, width: 3, prec: 3)[0]) + end +end diff --git a/jni/ruby/test/-ext-/test_recursion.rb b/jni/ruby/test/-ext-/test_recursion.rb new file mode 100644 index 0000000..06faf6d --- /dev/null +++ b/jni/ruby/test/-ext-/test_recursion.rb @@ -0,0 +1,35 @@ +# -*- coding: us-ascii -*- +require 'test/unit' + +class TestRecursion < Test::Unit::TestCase + require '-test-/recursion' + + def setup + @obj = Struct.new(:visited).new(false) + @obj.extend(Bug::Recursive) + end + + def test_recursive + def @obj.doit + self.visited = true + exec_recursive(:doit) + raise "recursive" + end + assert_raise_with_message(RuntimeError, "recursive") { + @obj.exec_recursive(:doit) + } + assert(@obj.visited, "obj.hash was not called") + end + + def test_recursive_outer + def @obj.doit + self.visited = true + exec_recursive_outer(:doit) + raise "recursive_outer should short circuit intermediate calls" + end + assert_nothing_raised { + @obj.exec_recursive_outer(:doit) + } + assert(@obj.visited, "obj.hash was not called") + end +end diff --git a/jni/ruby/test/-ext-/tracepoint/test_tracepoint.rb b/jni/ruby/test/-ext-/tracepoint/test_tracepoint.rb new file mode 100644 index 0000000..b5a6e76 --- /dev/null +++ b/jni/ruby/test/-ext-/tracepoint/test_tracepoint.rb @@ -0,0 +1,79 @@ +require 'test/unit' +require '-test-/tracepoint' + +class TestTracepointObj < Test::Unit::TestCase + def test_not_available_from_ruby + assert_raise ArgumentError do + TracePoint.trace(:obj_new){} + end + end + + def test_tracks_objspace_events + result = Bug.tracepoint_track_objspace_events{ + 99 + 'abc' + _="foobar" + Object.new + nil + } + + newobj_count, free_count, gc_start_count, gc_end_mark_count, gc_end_sweep_count, *newobjs = *result + assert_equal 2, newobj_count + assert_equal 2, newobjs.size + assert_equal 'foobar', newobjs[0] + assert_equal Object, newobjs[1].class + assert_operator free_count, :>=, 0 + assert_operator gc_start_count, :==, gc_end_mark_count + assert_operator gc_start_count, :>=, gc_end_sweep_count + end + + def test_tracks_objspace_count + stat1 = {} + stat2 = {} + GC.disable + GC.stat(stat1) + result = Bug.tracepoint_track_objspace_events{ + GC.enable + 1_000_000.times{''} + GC.disable + } + GC.stat(stat2) + GC.enable + + newobj_count, free_count, gc_start_count, gc_end_mark_count, gc_end_sweep_count, *newobjs = *result + + assert_operator stat2[:total_allocated_objects] - stat1[:total_allocated_objects], :>=, newobj_count + assert_operator 1_000_000, :<=, newobj_count + + assert_operator stat2[:total_freed_objects] + stat2[:heap_final_slots] - stat1[:total_freed_objects], :>=, free_count + assert_operator stat2[:count] - stat1[:count], :==, gc_start_count + + assert_operator gc_start_count, :==, gc_end_mark_count + assert_operator gc_start_count, :>=, gc_end_sweep_count + assert_operator stat2[:count] - stat1[:count] - 1, :<=, gc_end_sweep_count + end + + def test_tracepoint_specify_normal_and_internal_events + assert_raise(TypeError){ Bug.tracepoint_specify_normal_and_internal_events } + end + + def test_after_gc_start_hook_with_GC_stress + bug8492 = '[ruby-dev:47400] [Bug #8492]: infinite after_gc_start_hook reentrance' + assert_nothing_raised(Timeout::Error, bug8492) do + assert_in_out_err(%w[-r-test-/tracepoint], <<-'end;', /\A[1-9]/, timeout: 2) + stress, GC.stress = GC.stress, false + count = 0 + Bug.after_gc_start_hook = proc {count += 1} + begin + GC.stress = true + 3.times {Object.new} + ensure + GC.stress = stress + Bug.after_gc_start_hook = nil + end + puts count + end; + end + end + +end diff --git a/jni/ruby/test/-ext-/typeddata/test_typeddata.rb b/jni/ruby/test/-ext-/typeddata/test_typeddata.rb new file mode 100644 index 0000000..c24ad08 --- /dev/null +++ b/jni/ruby/test/-ext-/typeddata/test_typeddata.rb @@ -0,0 +1,16 @@ +require 'test/unit' +require "-test-/typeddata/typeddata" + +class Test_TypedData < Test::Unit::TestCase + def test_wrong_argtype + assert_raise_with_message(TypeError, "wrong argument type false (expected typed_data)") {Bug::TypedData.check(false)} + + assert_raise_with_message(TypeError, "wrong argument type true (expected typed_data)") {Bug::TypedData.check(true)} + + assert_raise_with_message(TypeError, "wrong argument type Symbol (expected typed_data)") {Bug::TypedData.check(:e)} + + assert_raise_with_message(TypeError, "wrong argument type Fixnum (expected typed_data)") {Bug::TypedData.check(0)} + + assert_raise_with_message(TypeError, "wrong argument type String (expected typed_data)") {Bug::TypedData.check("a")} + end +end diff --git a/jni/ruby/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb b/jni/ruby/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb new file mode 100644 index 0000000..e88dbef --- /dev/null +++ b/jni/ruby/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb @@ -0,0 +1,45 @@ +require 'test/unit' + +class TestWaitForSingleFD < Test::Unit::TestCase + require '-test-/wait_for_single_fd/wait_for_single_fd' + + def with_pipe + r, w = IO.pipe + begin + yield r, w + ensure + r.close unless r.closed? + w.close unless w.closed? + end + end + + def test_wait_for_valid_fd + with_pipe do |r,w| + rc = IO.wait_for_single_fd(w.fileno, RB_WAITFD_OUT, nil) + assert_equal RB_WAITFD_OUT, rc + end + end + + def test_wait_for_invalid_fd + # FreeBSD 8.2 or prior sticks this + # http://bugs.ruby-lang.org/issues/5524 + skip if /freebsd[1-8]/ =~ RUBY_PLATFORM + with_pipe do |r,w| + wfd = w.fileno + w.close + assert_raise(Errno::EBADF) do + IO.wait_for_single_fd(wfd, RB_WAITFD_OUT, nil) + end + end + end + + def test_wait_for_closed_pipe + with_pipe do |r,w| + w.close + rc = IO.wait_for_single_fd(r.fileno, RB_WAITFD_IN, nil) + assert_equal RB_WAITFD_IN, rc + end + end + + +end diff --git a/jni/ruby/test/-ext-/win32/test_console_attr.rb b/jni/ruby/test/-ext-/win32/test_console_attr.rb new file mode 100644 index 0000000..3afb2d9 --- /dev/null +++ b/jni/ruby/test/-ext-/win32/test_console_attr.rb @@ -0,0 +1,43 @@ +if /mswin|mingw/ =~ RUBY_PLATFORM and STDOUT.tty? + require '-test-/win32/console' + require 'io/console' + require 'test/unit' + + class Test_Win32Console < Test::Unit::TestCase + def reset + STDOUT.console_attribute(7) + end + + alias setup reset + alias teardown reset + + def test_default + info = STDOUT.console_info + assert_equal(7, info.attr); + end + + def test_reverse + print "\e[7m" + info = STDOUT.console_info + assert_equal(0x70, info.attr); + end + + def test_bold + print "\e[1m" + info = STDOUT.console_info + assert_equal(0x8, info.attr&0x8); + end + + def test_bold_reverse + print "\e[1;7m" + info = STDOUT.console_info + assert_equal(0xf0, info.attr); + end + + def test_reverse_bold + print "\e[7;1m" + info = STDOUT.console_info + assert_equal(0xf0, info.attr); + end + end +end diff --git a/jni/ruby/test/-ext-/win32/test_dln.rb b/jni/ruby/test/-ext-/win32/test_dln.rb new file mode 100644 index 0000000..2801ebe --- /dev/null +++ b/jni/ruby/test/-ext-/win32/test_dln.rb @@ -0,0 +1,34 @@ +require 'test/unit' +require 'tmpdir' +require 'rbconfig' + +module Bug + module Win32 + class TestDln < Test::Unit::TestCase + def test_check_imported + bug = '[Bug #6303]' + assert_in_out_err(['-r-test-/win32/dln', '-eexit'], '', [], [], bug, timeout: 10) + end + + def test_nonascii_load + bug9699 = '[ruby-core:61845] [Bug #9699]' + so = "-test-/win32/dln/empty." + RbConfig::CONFIG["DLEXT"] + so = $:.find {|d| d = ::File.join(d, so); break d if ::File.exist?(d)} + assert_not_nil(so) + Dir.mkdir(dir = ::File.join(testdir = Dir.mktmpdir("test"), "\u{30c6 30b9 30c8}")) + ::File.copy_stream(so, ::File.join(dir, ::File.basename(so))) + assert_separately(['-', bug9699, testdir, ::File.basename(so)], <<-'end;') + bug, dir, so = *ARGV + assert_nothing_raised(LoadError, bug) do + require ::File.join(dir, "\u{30c6 30b9 30c8}", so) + end + end; + ensure + ::File.unlink(::File.join(dir, ::File.basename(so))) rescue nil + Dir.rmdir(dir) rescue nil + Dir.rmdir(testdir) rescue nil + end + + end + end +end if /mswin|mingw/ =~ RUBY_PLATFORM diff --git a/jni/ruby/test/-ext-/win32/test_fd_setsize.rb b/jni/ruby/test/-ext-/win32/test_fd_setsize.rb new file mode 100644 index 0000000..6fe889c --- /dev/null +++ b/jni/ruby/test/-ext-/win32/test_fd_setsize.rb @@ -0,0 +1,24 @@ +require 'test/unit' + +module Bug + module Win32 + class TestFdSetSize < Test::Unit::TestCase + def test_select_with_unmatched_fd_setsize + bug6532 = '[ruby-core:44588]' + assert_in_out_err([], <<-INPUT, %w(:ok), [], bug6532) + require '-test-/win32/fd_setsize' + Bug::Win32.test_select + p :ok + INPUT + end + + def test_fdset_with_unmatched_fd_setsize + bug6532 = '[ruby-core:44588]' + assert_in_out_err([], <<-INPUT, %w(:ok), [], bug6532) + require '-test-/win32/fd_setsize' + p :ok if Bug::Win32.test_fdset + INPUT + end + end + end +end if /mswin|mingw/ =~ RUBY_PLATFORM |