From fcbf63e62c627deae76c1b8cb8c0876c536ed811 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 16 Mar 2020 18:49:26 +0900 Subject: Fresh start --- jni/ruby/test/-ext-/array/test_resize.rb | 29 ++ jni/ruby/test/-ext-/bignum/test_big2str.rb | 29 ++ jni/ruby/test/-ext-/bignum/test_bigzero.rb | 13 + jni/ruby/test/-ext-/bignum/test_div.rb | 28 ++ jni/ruby/test/-ext-/bignum/test_mul.rb | 137 ++++++ jni/ruby/test/-ext-/bignum/test_pack.rb | 398 +++++++++++++++++ jni/ruby/test/-ext-/bignum/test_str2big.rb | 37 ++ .../test/-ext-/bug_reporter/test_bug_reporter.rb | 25 ++ jni/ruby/test/-ext-/class/test_class2name.rb | 18 + jni/ruby/test/-ext-/debug/test_debug.rb | 58 +++ jni/ruby/test/-ext-/debug/test_profile_frames.rb | 104 +++++ jni/ruby/test/-ext-/exception/test_data_error.rb | 13 + jni/ruby/test/-ext-/exception/test_enc_raise.rb | 15 + jni/ruby/test/-ext-/exception/test_ensured.rb | 31 ++ jni/ruby/test/-ext-/file/test_stat.rb | 14 + jni/ruby/test/-ext-/float/test_nextafter.rb | 57 +++ jni/ruby/test/-ext-/funcall/test_passing_block.rb | 22 + jni/ruby/test/-ext-/hash/test_delete.rb | 19 + jni/ruby/test/-ext-/iseq_load/test_iseq_load.rb | 95 +++++ jni/ruby/test/-ext-/iter/test_iter_break.rb | 15 + jni/ruby/test/-ext-/iter/test_yield_block.rb | 21 + jni/ruby/test/-ext-/load/test_dot_dot.rb | 10 + jni/ruby/test/-ext-/marshal/test_usrmarshal.rb | 32 ++ jni/ruby/test/-ext-/method/test_arity.rb | 37 ++ jni/ruby/test/-ext-/num2int/test_num2int.rb | 267 ++++++++++++ .../test/-ext-/path_to_class/test_path_to_class.rb | 12 + .../test/-ext-/postponed_job/test_postponed_job.rb | 28 ++ jni/ruby/test/-ext-/proc/test_bmethod.rb | 37 ++ jni/ruby/test/-ext-/rational/test_rat.rb | 31 ++ jni/ruby/test/-ext-/st/test_foreach.rb | 15 + jni/ruby/test/-ext-/st/test_numhash.rb | 49 +++ jni/ruby/test/-ext-/st/test_update.rb | 50 +++ jni/ruby/test/-ext-/string/test_coderange.rb | 59 +++ jni/ruby/test/-ext-/string/test_cstr.rb | 119 ++++++ jni/ruby/test/-ext-/string/test_ellipsize.rb | 46 ++ jni/ruby/test/-ext-/string/test_enc_associate.rb | 12 + jni/ruby/test/-ext-/string/test_enc_str_buf_cat.rb | 15 + jni/ruby/test/-ext-/string/test_modify_expand.rb | 15 + jni/ruby/test/-ext-/string/test_nofree.rb | 10 + jni/ruby/test/-ext-/string/test_normalize.rb | 106 +++++ jni/ruby/test/-ext-/string/test_qsort.rb | 19 + jni/ruby/test/-ext-/string/test_set_len.rb | 25 ++ jni/ruby/test/-ext-/struct/test_member.rb | 15 + .../test/-ext-/symbol/test_inadvertent_creation.rb | 473 +++++++++++++++++++++ jni/ruby/test/-ext-/symbol/test_type.rb | 124 ++++++ jni/ruby/test/-ext-/test_bug-3571.rb | 20 + jni/ruby/test/-ext-/test_bug-3662.rb | 10 + jni/ruby/test/-ext-/test_bug-5832.rb | 21 + jni/ruby/test/-ext-/test_printf.rb | 186 ++++++++ jni/ruby/test/-ext-/test_recursion.rb | 35 ++ jni/ruby/test/-ext-/tracepoint/test_tracepoint.rb | 79 ++++ jni/ruby/test/-ext-/typeddata/test_typeddata.rb | 16 + .../wait_for_single_fd/test_wait_for_single_fd.rb | 45 ++ jni/ruby/test/-ext-/win32/test_console_attr.rb | 43 ++ jni/ruby/test/-ext-/win32/test_dln.rb | 34 ++ jni/ruby/test/-ext-/win32/test_fd_setsize.rb | 24 ++ 56 files changed, 3297 insertions(+) create mode 100644 jni/ruby/test/-ext-/array/test_resize.rb create mode 100644 jni/ruby/test/-ext-/bignum/test_big2str.rb create mode 100644 jni/ruby/test/-ext-/bignum/test_bigzero.rb create mode 100644 jni/ruby/test/-ext-/bignum/test_div.rb create mode 100644 jni/ruby/test/-ext-/bignum/test_mul.rb create mode 100644 jni/ruby/test/-ext-/bignum/test_pack.rb create mode 100644 jni/ruby/test/-ext-/bignum/test_str2big.rb create mode 100644 jni/ruby/test/-ext-/bug_reporter/test_bug_reporter.rb create mode 100644 jni/ruby/test/-ext-/class/test_class2name.rb create mode 100644 jni/ruby/test/-ext-/debug/test_debug.rb create mode 100644 jni/ruby/test/-ext-/debug/test_profile_frames.rb create mode 100644 jni/ruby/test/-ext-/exception/test_data_error.rb create mode 100644 jni/ruby/test/-ext-/exception/test_enc_raise.rb create mode 100644 jni/ruby/test/-ext-/exception/test_ensured.rb create mode 100644 jni/ruby/test/-ext-/file/test_stat.rb create mode 100644 jni/ruby/test/-ext-/float/test_nextafter.rb create mode 100644 jni/ruby/test/-ext-/funcall/test_passing_block.rb create mode 100644 jni/ruby/test/-ext-/hash/test_delete.rb create mode 100644 jni/ruby/test/-ext-/iseq_load/test_iseq_load.rb create mode 100644 jni/ruby/test/-ext-/iter/test_iter_break.rb create mode 100644 jni/ruby/test/-ext-/iter/test_yield_block.rb create mode 100644 jni/ruby/test/-ext-/load/test_dot_dot.rb create mode 100644 jni/ruby/test/-ext-/marshal/test_usrmarshal.rb create mode 100644 jni/ruby/test/-ext-/method/test_arity.rb create mode 100644 jni/ruby/test/-ext-/num2int/test_num2int.rb create mode 100644 jni/ruby/test/-ext-/path_to_class/test_path_to_class.rb create mode 100644 jni/ruby/test/-ext-/postponed_job/test_postponed_job.rb create mode 100644 jni/ruby/test/-ext-/proc/test_bmethod.rb create mode 100644 jni/ruby/test/-ext-/rational/test_rat.rb create mode 100644 jni/ruby/test/-ext-/st/test_foreach.rb create mode 100644 jni/ruby/test/-ext-/st/test_numhash.rb create mode 100644 jni/ruby/test/-ext-/st/test_update.rb create mode 100644 jni/ruby/test/-ext-/string/test_coderange.rb create mode 100644 jni/ruby/test/-ext-/string/test_cstr.rb create mode 100644 jni/ruby/test/-ext-/string/test_ellipsize.rb create mode 100644 jni/ruby/test/-ext-/string/test_enc_associate.rb create mode 100644 jni/ruby/test/-ext-/string/test_enc_str_buf_cat.rb create mode 100644 jni/ruby/test/-ext-/string/test_modify_expand.rb create mode 100644 jni/ruby/test/-ext-/string/test_nofree.rb create mode 100644 jni/ruby/test/-ext-/string/test_normalize.rb create mode 100644 jni/ruby/test/-ext-/string/test_qsort.rb create mode 100644 jni/ruby/test/-ext-/string/test_set_len.rb create mode 100644 jni/ruby/test/-ext-/struct/test_member.rb create mode 100644 jni/ruby/test/-ext-/symbol/test_inadvertent_creation.rb create mode 100644 jni/ruby/test/-ext-/symbol/test_type.rb create mode 100644 jni/ruby/test/-ext-/test_bug-3571.rb create mode 100644 jni/ruby/test/-ext-/test_bug-3662.rb create mode 100644 jni/ruby/test/-ext-/test_bug-5832.rb create mode 100644 jni/ruby/test/-ext-/test_printf.rb create mode 100644 jni/ruby/test/-ext-/test_recursion.rb create mode 100644 jni/ruby/test/-ext-/tracepoint/test_tracepoint.rb create mode 100644 jni/ruby/test/-ext-/typeddata/test_typeddata.rb create mode 100644 jni/ruby/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb create mode 100644 jni/ruby/test/-ext-/win32/test_console_attr.rb create mode 100644 jni/ruby/test/-ext-/win32/test_dln.rb create mode 100644 jni/ruby/test/-ext-/win32/test_fd_setsize.rb (limited to 'jni/ruby/test/-ext-') 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 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 = < 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 `
'", + ] + 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 -- cgit v1.2.3