diff options
Diffstat (limited to 'test/ruby/test_eval.rb')
| -rw-r--r-- | test/ruby/test_eval.rb | 348 |
1 files changed, 312 insertions, 36 deletions
diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb index 6b3fea7bb4..299165fb34 100644 --- a/test/ruby/test_eval.rb +++ b/test/ruby/test_eval.rb @@ -1,7 +1,213 @@ require 'test/unit' +require_relative 'envutil' class TestEval < Test::Unit::TestCase - # eval with binding + + @ivar = 12 + @@cvar = 13 + $gvar__eval = 14 + Const = 15 + + def ruby(*args) + args = ['-e', '$>.write($<.read)'] if args.empty? + ruby = EnvUtil.rubybin + f = IO.popen([ruby] + args, 'r+') + yield(f) + ensure + f.close unless !f || f.closed? + end + + def test_eval_basic + assert_equal nil, eval("nil") + assert_equal true, eval("true") + assert_equal false, eval("false") + assert_equal self, eval("self") + assert_equal 1, eval("1") + assert_equal :sym, eval(":sym") + + assert_equal 11, eval("11") + @ivar = 12 + assert_equal 12, eval("@ivar") + assert_equal 13, eval("@@cvar") + assert_equal 14, eval("$gvar__eval") + assert_equal 15, eval("Const") + + assert_equal 16, eval("7 + 9") + assert_equal 17, eval("17.to_i") + assert_equal "18", eval(%q("18")) + assert_equal "19", eval(%q("1#{9}")) + + 1.times { + assert_equal 12, eval("@ivar") + assert_equal 13, eval("@@cvar") + assert_equal 14, eval("$gvar__eval") + assert_equal 15, eval("Const") + } + end + + def test_eval_binding_basic + assert_equal nil, eval("nil", binding()) + assert_equal true, eval("true", binding()) + assert_equal false, eval("false", binding()) + assert_equal self, eval("self", binding()) + assert_equal 1, eval("1", binding()) + assert_equal :sym, eval(":sym", binding()) + + assert_equal 11, eval("11", binding()) + @ivar = 12 + assert_equal 12, eval("@ivar", binding()) + assert_equal 13, eval("@@cvar", binding()) + assert_equal 14, eval("$gvar__eval", binding()) + assert_equal 15, eval("Const", binding()) + + assert_equal 16, eval("7 + 9", binding()) + assert_equal 17, eval("17.to_i", binding()) + assert_equal "18", eval(%q("18"), binding()) + assert_equal "19", eval(%q("1#{9}"), binding()) + + 1.times { + assert_equal 12, eval("@ivar") + assert_equal 13, eval("@@cvar") + assert_equal 14, eval("$gvar__eval") + assert_equal 15, eval("Const") + } + end + + def test_module_eval_string_basic + c = self.class + assert_equal nil, c.module_eval("nil") + assert_equal true, c.module_eval("true") + assert_equal false, c.module_eval("false") + assert_equal c, c.module_eval("self") + assert_equal :sym, c.module_eval(":sym") + assert_equal 11, c.module_eval("11") + @ivar = 12 + assert_equal 12, c.module_eval("@ivar") + assert_equal 13, c.module_eval("@@cvar") + assert_equal 14, c.module_eval("$gvar__eval") + assert_equal 15, c.module_eval("Const") + assert_equal 16, c.module_eval("7 + 9") + assert_equal 17, c.module_eval("17.to_i") + assert_equal "18", c.module_eval(%q("18")) + assert_equal "19", c.module_eval(%q("1#{9}")) + + @ivar = 12 + 1.times { + assert_equal 12, c.module_eval("@ivar") + assert_equal 13, c.module_eval("@@cvar") + assert_equal 14, c.module_eval("$gvar__eval") + assert_equal 15, c.module_eval("Const") + } + end + + def test_module_eval_block_basic + c = self.class + assert_equal nil, c.module_eval { nil } + assert_equal true, c.module_eval { true } + assert_equal false, c.module_eval { false } + assert_equal c, c.module_eval { self } + assert_equal :sym, c.module_eval { :sym } + assert_equal 11, c.module_eval { 11 } + @ivar = 12 + assert_equal 12, c.module_eval { @ivar } + assert_equal 13, c.module_eval { @@cvar } + assert_equal 14, c.module_eval { $gvar__eval } + assert_equal 15, c.module_eval { Const } + assert_equal 16, c.module_eval { 7 + 9 } + assert_equal 17, c.module_eval { "17".to_i } + assert_equal "18", c.module_eval { "18" } + assert_equal "19", c.module_eval { "1#{9}" } + + @ivar = 12 + 1.times { + assert_equal 12, c.module_eval { @ivar } + assert_equal 13, c.module_eval { @@cvar } + assert_equal 14, c.module_eval { $gvar__eval } + assert_equal 15, c.module_eval { Const } + } + end + + def forall_TYPE(mid) + objects = [Object.new, [], nil, true, false, 77, :sym] # TODO: check + objects.each do |obj| + obj.instance_variable_set :@ivar, 12 + send mid, obj + end + end + + def test_instance_eval_string_basic + forall_TYPE :instance_eval_string_basic_i + end + + def instance_eval_string_basic_i(o) + assert_equal nil, o.instance_eval("nil") + assert_equal true, o.instance_eval("true") + assert_equal false, o.instance_eval("false") + assert_equal o, o.instance_eval("self") + assert_equal 1, o.instance_eval("1") + assert_equal :sym, o.instance_eval(":sym") + + assert_equal 11, o.instance_eval("11") + assert_equal 12, o.instance_eval("@ivar") + assert_equal 13, o.instance_eval("@@cvar") + assert_equal 14, o.instance_eval("$gvar__eval") + assert_equal 15, o.instance_eval("Const") + assert_equal 16, o.instance_eval("7 + 9") + assert_equal 17, o.instance_eval("17.to_i") + assert_equal "18", o.instance_eval(%q("18")) + assert_equal "19", o.instance_eval(%q("1#{9}")) + + 1.times { + assert_equal 12, o.instance_eval("@ivar") + assert_equal 13, o.instance_eval("@@cvar") + assert_equal 14, o.instance_eval("$gvar__eval") + assert_equal 15, o.instance_eval("Const") + } + end + + def test_instance_eval_block_basic + forall_TYPE :instance_eval_block_basic_i + end + + def instance_eval_block_basic_i(o) + assert_equal nil, o.instance_eval { nil } + assert_equal true, o.instance_eval { true } + assert_equal false, o.instance_eval { false } + assert_equal o, o.instance_eval { self } + assert_equal 1, o.instance_eval { 1 } + assert_equal :sym, o.instance_eval { :sym } + + assert_equal 11, o.instance_eval { 11 } + assert_equal 12, o.instance_eval { @ivar } + assert_equal 13, o.instance_eval { @@cvar } + assert_equal 14, o.instance_eval { $gvar__eval } + assert_equal 15, o.instance_eval { Const } + assert_equal 16, o.instance_eval { 7 + 9 } + assert_equal 17, o.instance_eval { 17.to_i } + assert_equal "18", o.instance_eval { "18" } + assert_equal "19", o.instance_eval { "1#{9}" } + + 1.times { + assert_equal 12, o.instance_eval { @ivar } + assert_equal 13, o.instance_eval { @@cvar } + assert_equal 14, o.instance_eval { $gvar__eval } + assert_equal 15, o.instance_eval { Const } + } + end + + def test_instance_eval_cvar + [Object.new, [], 7, :sym, true, false, nil].each do |obj| + assert_equal(13, obj.instance_eval("@@cvar")) + assert_equal(13, obj.instance_eval{@@cvar}) + # assert_raise(NameError){obj.instance_eval("@@cvar")} + # assert_raise(NameError){obj.instance_eval{@@cvar}} + end + end + + # + # From ruby/test/ruby/test_eval.rb + # + def test_ev local1 = "local1" lambda { @@ -10,7 +216,7 @@ class TestEval < Test::Unit::TestCase }.call end - def test_eval + def test_eval_orig assert_nil(eval("")) $bad=false eval 'while false; $bad = true; print "foo\n" end' @@ -66,16 +272,19 @@ class TestEval < Test::Unit::TestCase end assert(!$bad) - x = proc{} - eval "i4 = 1", x - assert_equal(1, eval("i4", x)) - x = proc{proc{}}.call - eval "i4 = 22", x - assert_equal(22, eval("i4", x)) - $x = [] - x = proc{proc{}}.call - eval "(0..9).each{|i5| $x[i5] = proc{i5*2}}", x - assert_equal(8, $x[4].call) + if false + # Ruby 2.0 doesn't see Proc as Binding + x = proc{} + eval "i4 = 1", x + assert_equal(1, eval("i4", x)) + x = proc{proc{}}.call + eval "i4 = 22", x + assert_equal(22, eval("i4", x)) + $x = [] + x = proc{proc{}}.call + eval "(0..9).each{|i5| $x[i5] = proc{i5*2}}", x + assert_equal(8, $x[4].call) + end x = binding eval "i = 1", x @@ -98,55 +307,62 @@ class TestEval < Test::Unit::TestCase foo22 = 5 proc{foo11=22}.call proc{foo22=55}.call - assert_equal(eval("foo11"), eval("foo11", p)) - assert_equal(1, eval("foo11")) + # assert_equal(eval("foo11"), eval("foo11", p)) + # assert_equal(1, eval("foo11")) assert_equal(eval("foo22"), eval("foo22", p)) assert_equal(55, eval("foo22")) }.call - p1 = proc{i7 = 0; proc{i7}}.call - assert_equal(0, p1.call) - eval "i7=5", p1 - assert_equal(5, p1.call) - assert(!defined?(i7)) + if false + # Ruby 2.0 doesn't see Proc as Binding + p1 = proc{i7 = 0; proc{i7}}.call + assert_equal(0, p1.call) + eval "i7=5", p1 + assert_equal(5, p1.call) + assert(!defined?(i7)) + end - p1 = proc{i7 = 0; proc{i7}}.call - i7 = nil - assert_equal(0, p1.call) - eval "i7=1", p1 - assert_equal(1, p1.call) - eval "i7=5", p1 - assert_equal(5, p1.call) - assert_nil(i7) + if false + # Ruby 2.0 doesn't see Proc as Binding + p1 = proc{i7 = 0; proc{i7}}.call + i7 = nil + assert_equal(0, p1.call) + eval "i7=1", p1 + assert_equal(1, p1.call) + eval "i7=5", p1 + assert_equal(5, p1.call) + assert_nil(i7) + end end - def test_nil_instance_eval_cvar # [ruby-dev:24103] + def test_nil_instance_eval_cvar def nil.test_binding binding end bb = eval("nil.instance_eval \"binding\"", nil.test_binding) - assert_raise(NameError) { eval("@@a", bb) } + assert_raise(NameError, "[ruby-dev:24103]") { eval("@@a", bb) } class << nil remove_method :test_binding end end - def test_fixnum_instance_eval_cvar # [ruby-dev:24213] - assert_raise(NameError) { 1.instance_eval "@@a" } + def test_fixnum_instance_eval_cvar + assert_raise(NameError, "[ruby-dev:24213]") { 1.instance_eval "@@a" } end - def test_cvar_scope_with_instance_eval # [ruby-dev:24223] + def test_cvar_scope_with_instance_eval + # TODO: check Fixnum.class_eval "@@test_cvar_scope_with_instance_eval = 1" # depends on [ruby-dev:24229] @@test_cvar_scope_with_instance_eval = 4 - assert_equal(4, 1.instance_eval("@@test_cvar_scope_with_instance_eval")) + assert_equal(4, 1.instance_eval("@@test_cvar_scope_with_instance_eval"), "[ruby-dev:24223]") Fixnum.__send__(:remove_class_variable, :@@test_cvar_scope_with_instance_eval) end - def test_eval_and_define_method # [ruby-dev:24228] - assert_nothing_raised { + def test_eval_and_define_method + assert_nothing_raised("[ruby-dev:24228]") { def temporally_method_for_test_eval_and_define_method(&block) lambda { - class << Object.new; self end.__send__(:define_method, :zzz, &block) + class << Object.new; self end.send(:define_method, :zzz, &block) } end v = eval("temporally_method_for_test_eval_and_define_method {}") @@ -154,4 +370,64 @@ class TestEval < Test::Unit::TestCase v.call } end + + def test_define_method_block + cc = Class.new do + define_method(:foo) {|&block| + block.call if block + } + end + + c = cc.new + x = "ng" + c.foo() {x = "ok"} + assert_equal("ok", x) + end + + def test_eval_using_integer_as_binding + assert_raise(TypeError) { eval("", 1) } + end + + def test_eval_raise + assert_raise(RuntimeError) { eval("raise ''") } + end + + def test_eval_using_untainted_binding_under_safe4 + assert_raise(SecurityError) do + Thread.new do + b = binding + $SAFE = 4 + eval("", b) + end.join + end + end + + def test_eval_with_toplevel_binding # [ruby-dev:37142] + ruby("-e", "x = 0; eval('p x', TOPLEVEL_BINDING)") do |f| + f.close_write + assert_equal("0", f.read.chomp) + end + end + + def test_eval_ascii_incompatible + assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-16be"))} + assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-16le"))} + assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-32be"))} + assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-32le"))} + end + + def test_instance_eval_method_proc + bug3860 = Class.new do + def initialize(a); + @a=a + end + def get(*args) + @a + end + end + foo = bug3860.new 1 + foo_pr = foo.method(:get).to_proc + result = foo.instance_eval(&foo_pr) + assert_equal(1, result, 'Bug #3786, Bug #3860, [ruby-core:32501]') + end end |
