summaryrefslogtreecommitdiff
path: root/jni/ruby/test/ruby/test_optimization.rb
diff options
context:
space:
mode:
Diffstat (limited to 'jni/ruby/test/ruby/test_optimization.rb')
-rw-r--r--jni/ruby/test/ruby/test_optimization.rb292
1 files changed, 292 insertions, 0 deletions
diff --git a/jni/ruby/test/ruby/test_optimization.rb b/jni/ruby/test/ruby/test_optimization.rb
new file mode 100644
index 0000000..4a5484e
--- /dev/null
+++ b/jni/ruby/test/ruby/test_optimization.rb
@@ -0,0 +1,292 @@
+require 'test/unit'
+
+class TestRubyOptimization < Test::Unit::TestCase
+
+ BIGNUM_POS_MIN_32 = 1073741824 # 2 ** 30
+ if BIGNUM_POS_MIN_32.kind_of?(Fixnum)
+ FIXNUM_MAX = 4611686018427387903 # 2 ** 62 - 1
+ else
+ FIXNUM_MAX = 1073741823 # 2 ** 30 - 1
+ end
+
+ BIGNUM_NEG_MAX_32 = -1073741825 # -2 ** 30 - 1
+ if BIGNUM_NEG_MAX_32.kind_of?(Fixnum)
+ FIXNUM_MIN = -4611686018427387904 # -2 ** 62
+ else
+ FIXNUM_MIN = -1073741824 # -2 ** 30
+ end
+
+ def assert_redefine_method(klass, method, code, msg = nil)
+ assert_separately([], <<-"end;")# do
+ class #{klass}
+ undef #{method}
+ def #{method}(*args)
+ args[0]
+ end
+ end
+ #{code}
+ end;
+ end
+
+ def test_fixnum_plus
+ a, b = 1, 2
+ assert_equal 3, a + b
+ assert_instance_of Fixnum, FIXNUM_MAX
+ assert_instance_of Bignum, FIXNUM_MAX + 1
+
+ assert_equal 21, 10 + 11
+ assert_redefine_method('Fixnum', '+', 'assert_equal 11, 10 + 11')
+ end
+
+ def test_fixnum_minus
+ assert_equal 5, 8 - 3
+ assert_instance_of Fixnum, FIXNUM_MIN
+ assert_instance_of Bignum, FIXNUM_MIN - 1
+
+ assert_equal 5, 8 - 3
+ assert_redefine_method('Fixnum', '-', 'assert_equal 3, 8 - 3')
+ end
+
+ def test_fixnum_mul
+ assert_equal 15, 3 * 5
+ assert_redefine_method('Fixnum', '*', 'assert_equal 5, 3 * 5')
+ end
+
+ def test_fixnum_div
+ assert_equal 3, 15 / 5
+ assert_redefine_method('Fixnum', '/', 'assert_equal 5, 15 / 5')
+ end
+
+ def test_fixnum_mod
+ assert_equal 1, 8 % 7
+ assert_redefine_method('Fixnum', '%', 'assert_equal 7, 8 % 7')
+ end
+
+ def test_float_plus
+ assert_equal 4.0, 2.0 + 2.0
+ assert_redefine_method('Float', '+', 'assert_equal 2.0, 2.0 + 2.0')
+ end
+
+ def test_float_minus
+ assert_equal 4.0, 2.0 + 2.0
+ assert_redefine_method('Float', '+', 'assert_equal 2.0, 2.0 + 2.0')
+ end
+
+ def test_float_mul
+ assert_equal 29.25, 4.5 * 6.5
+ assert_redefine_method('Float', '*', 'assert_equal 6.5, 4.5 * 6.5')
+ end
+
+ def test_float_div
+ assert_in_delta 0.63063063063063063, 4.2 / 6.66
+ assert_redefine_method('Float', '/', 'assert_equal 6.66, 4.2 / 6.66', "[Bug #9238]")
+ end
+
+ def test_string_length
+ assert_equal 6, "string".length
+ assert_redefine_method('String', 'length', 'assert_nil "string".length')
+ end
+
+ def test_string_size
+ assert_equal 6, "string".size
+ assert_redefine_method('String', 'size', 'assert_nil "string".size')
+ end
+
+ def test_string_empty?
+ assert_equal true, "".empty?
+ assert_equal false, "string".empty?
+ assert_redefine_method('String', 'empty?', 'assert_nil "string".empty?')
+ end
+
+ def test_string_plus
+ assert_equal "", "" + ""
+ assert_equal "x", "x" + ""
+ assert_equal "x", "" + "x"
+ assert_equal "ab", "a" + "b"
+ assert_redefine_method('String', '+', 'assert_equal "b", "a" + "b"')
+ end
+
+ def test_string_succ
+ assert_equal 'b', 'a'.succ
+ assert_equal 'B', 'A'.succ
+ end
+
+ def test_string_format
+ assert_equal '2', '%d' % 2
+ assert_redefine_method('String', '%', 'assert_equal 2, "%d" % 2')
+ end
+
+ def test_string_freeze
+ assert_equal "foo", "foo".freeze
+ assert_equal "foo".freeze.object_id, "foo".freeze.object_id
+ assert_redefine_method('String', 'freeze', 'assert_nil "foo".freeze')
+ end
+
+ def test_string_eq_neq
+ %w(== !=).each do |m|
+ assert_redefine_method('String', m, <<-end)
+ assert_equal :b, ("a" #{m} "b").to_sym
+ b = 'b'
+ assert_equal :b, ("a" #{m} b).to_sym
+ assert_equal :b, (b #{m} "b").to_sym
+ end
+ end
+ end
+
+ def test_string_ltlt
+ assert_equal "", "" << ""
+ assert_equal "x", "x" << ""
+ assert_equal "x", "" << "x"
+ assert_equal "ab", "a" << "b"
+ assert_redefine_method('String', '<<', 'assert_equal "b", "a" << "b"')
+ end
+
+ def test_array_plus
+ assert_equal [1,2], [1]+[2]
+ assert_redefine_method('Array', '+', 'assert_equal [2], [1]+[2]')
+ end
+
+ def test_array_minus
+ assert_equal [2], [1,2] - [1]
+ assert_redefine_method('Array', '-', 'assert_equal [1], [1,2]-[1]')
+ end
+
+ def test_array_length
+ assert_equal 0, [].length
+ assert_equal 3, [1,2,3].length
+ assert_redefine_method('Array', 'length', 'assert_nil([].length); assert_nil([1,2,3].length)')
+ end
+
+ def test_array_empty?
+ assert_equal true, [].empty?
+ assert_equal false, [1,2,3].empty?
+ assert_redefine_method('Array', 'empty?', 'assert_nil([].empty?); assert_nil([1,2,3].empty?)')
+ end
+
+ def test_hash_length
+ assert_equal 0, {}.length
+ assert_equal 1, {1=>1}.length
+ assert_redefine_method('Hash', 'length', 'assert_nil({}.length); assert_nil({1=>1}.length)')
+ end
+
+ def test_hash_empty?
+ assert_equal true, {}.empty?
+ assert_equal false, {1=>1}.empty?
+ assert_redefine_method('Hash', 'empty?', 'assert_nil({}.empty?); assert_nil({1=>1}.empty?)')
+ end
+
+ def test_hash_aref_with
+ h = { "foo" => 1 }
+ assert_equal 1, h["foo"]
+ assert_redefine_method('Hash', '[]', <<-end)
+ h = { "foo" => 1 }
+ assert_equal "foo", h["foo"]
+ end
+ end
+
+ def test_hash_aset_with
+ h = {}
+ assert_equal 1, h["foo"] = 1
+ assert_redefine_method('Hash', '[]=', <<-end)
+ h = {}
+ assert_equal 1, h["foo"] = 1, "assignment always returns value set"
+ assert_nil h["foo"]
+ end
+ end
+
+ class MyObj
+ def ==(other)
+ true
+ end
+ end
+
+ def test_eq
+ assert_equal true, nil == nil
+ assert_equal true, 1 == 1
+ assert_equal true, 'string' == 'string'
+ assert_equal true, 1 == MyObj.new
+ assert_equal false, nil == MyObj.new
+ assert_equal true, MyObj.new == 1
+ assert_equal true, MyObj.new == nil
+ end
+
+ def test_tailcall
+ bug4082 = '[ruby-core:33289]'
+
+ option = {
+ tailcall_optimization: true,
+ trace_instruction: false,
+ }
+ RubyVM::InstructionSequence.new(<<-EOF, "Bug#4082", bug4082, nil, option).eval
+ class #{self.class}::Tailcall
+ def fact_helper(n, res)
+ if n == 1
+ res
+ else
+ fact_helper(n - 1, n * res)
+ end
+ end
+ def fact(n)
+ fact_helper(n, 1)
+ end
+ end
+ EOF
+ assert_equal(9131, Tailcall.new.fact(3000).to_s.size, bug4082)
+ end
+
+ def test_tailcall_with_block
+ bug6901 = '[ruby-dev:46065]'
+
+ option = {
+ tailcall_optimization: true,
+ trace_instruction: false,
+ }
+ RubyVM::InstructionSequence.new(<<-EOF, "Bug#6901", bug6901, nil, option).eval
+ def identity(val)
+ val
+ end
+
+ def delay
+ -> {
+ identity(yield)
+ }
+ end
+ EOF
+ assert_equal(123, delay { 123 }.call, bug6901)
+ end
+
+ class Bug10557
+ def [](_)
+ block_given?
+ end
+
+ def []=(_, _)
+ block_given?
+ end
+ end
+
+ def test_block_given_aset_aref
+ bug10557 = '[ruby-core:66595]'
+ assert_equal(true, Bug10557.new.[](nil){}, bug10557)
+ assert_equal(true, Bug10557.new.[](0){}, bug10557)
+ assert_equal(true, Bug10557.new.[](false){}, bug10557)
+ assert_equal(true, Bug10557.new.[](''){}, bug10557)
+ assert_equal(true, Bug10557.new.[]=(nil, 1){}, bug10557)
+ assert_equal(true, Bug10557.new.[]=(0, 1){}, bug10557)
+ assert_equal(true, Bug10557.new.[]=(false, 1){}, bug10557)
+ assert_equal(true, Bug10557.new.[]=('', 1){}, bug10557)
+ end
+
+ def test_string_freeze_block
+ assert_separately([], <<-"end;")# do
+ class String
+ undef freeze
+ def freeze
+ block_given?
+ end
+ end
+ assert_equal(true, "block".freeze {})
+ assert_equal(false, "block".freeze)
+ end;
+ end
+end