From f09f597422b4130727638e41b1332edac1514642 Mon Sep 17 00:00:00 2001 From: mame Date: Wed, 14 May 2008 12:52:17 +0000 Subject: * test/ruby/test_object.rb: new tests to achieve over 90% test coverage of object.c, eval.c and eval_method.c. * test/ruby/test_module.rb: ditto. * test/ruby/test_trace.rb: ditto. * test/ruby/test_integer.rb: ditto. * test/ruby/test_float.rb: ditto. * test/ruby/test_method.rb: ditto. * test/ruby/test_variable.rb: ditto. * test/ruby/test_eval.rb: ditto. * test/ruby/test_exception.rb: ditto. * test/ruby/test_class.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16418 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/ruby/test_class.rb | 28 ++++ test/ruby/test_eval.rb | 17 +++ test/ruby/test_exception.rb | 62 ++++++++ test/ruby/test_float.rb | 22 +++ test/ruby/test_integer.rb | 5 + test/ruby/test_method.rb | 18 +++ test/ruby/test_module.rb | 331 ++++++++++++++++++++++++++++++++++++++++++ test/ruby/test_object.rb | 339 ++++++++++++++++++++++++++++++++++++++++++++ test/ruby/test_trace.rb | 28 ++++ test/ruby/test_variable.rb | 9 ++ 10 files changed, 859 insertions(+) create mode 100644 test/ruby/test_object.rb (limited to 'test/ruby') diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb index fa8a40f39b..d4813a5f07 100644 --- a/test/ruby/test_class.rb +++ b/test/ruby/test_class.rb @@ -77,4 +77,32 @@ class TestClass < Test::Unit::TestCase assert_equal(BasicObject, ClassTwo.superclass.superclass.superclass) end + def test_class_cmp + assert_raise(TypeError) { Class.new <= 1 } + assert_raise(TypeError) { Class.new >= 1 } + assert_nil(Class.new <=> 1) + end + + def test_class_initialize + assert_raise(TypeError) do + Class.new.instance_eval { initialize } + end + end + + def test_instanciate_singleton_class + c = class << Object.new; self; end + assert_raise(TypeError) { c.new } + end + + def test_superclass_of_basicobject + assert_equal(nil, BasicObject.superclass) + end + + def test_module_function + c = Class.new + assert_raise(TypeError) do + Module.instance_method(:module_function).bind(c).call(:foo) + end + end + end diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb index 6e39374a9c..876aaafc08 100644 --- a/test/ruby/test_eval.rb +++ b/test/ruby/test_eval.rb @@ -358,4 +358,21 @@ class TestEval < Test::Unit::TestCase } 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 end diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index 4c27c52f3c..6c2cedd242 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -1,6 +1,11 @@ require 'test/unit' +require_relative 'envutil' class TestException < Test::Unit::TestCase + def ruby(*r, &b) + EnvUtil.rubyexec(*r, &b) + end + def test_exception begin raise "this must be handled" @@ -184,4 +189,61 @@ class TestException < Test::Unit::TestCase assert(false) end end + + def test_raise_with_wrong_number_of_arguments + assert_raise(TypeError) { raise nil } + assert_raise(TypeError) { raise 1, 1 } + assert_raise(ArgumentError) { raise 1, 1, 1, 1 } + end + + def test_errat + ruby do |w, r, e| + w.puts "p $@" + w.close + assert_equal("nil", r.read.chomp) + assert_equal("", e.read.chomp) + end + + ruby do |w, r, e| + w.puts "$@ = 1" + w.close + assert_equal("", r.read.chomp) + assert_match(/\$! not set \(ArgumentError\)$/, e.read.chomp) + end + + ruby do |w, r, e| + w.puts "begin" + w.puts " raise" + w.puts "rescue" + w.puts " $@ = 1" + w.puts "end" + w.close + assert_equal("", r.read.chomp) + assert_match(/backtrace must be Array of String \(TypeError\)$/, e.read.chomp) + end + + ruby do |w, r, e| + w.puts "begin" + w.puts " raise" + w.puts "rescue" + w.puts " $@ = 'foo'" + w.puts " raise" + w.puts "end" + w.close + assert_equal("", r.read.chomp) + assert_match(/^foo: unhandled exception$/, e.read.chomp) + end + + ruby do |w, r, e| + w.puts "begin" + w.puts " raise" + w.puts "rescue" + w.puts " $@ = %w(foo bar baz)" + w.puts " raise" + w.puts "end" + w.close + assert_equal("", r.read.chomp) + assert_match(/^foo: unhandled exception\s+from bar\s+from baz$/, e.read.chomp) + end + end end diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb index 9c4550e38d..ff4cf3fba1 100644 --- a/test/ruby/test_float.rb +++ b/test/ruby/test_float.rb @@ -405,4 +405,26 @@ class TestFloat < Test::Unit::TestCase } end + def test_Float + assert_in_delta(0.125, Float("0.1_2_5"), 0.00001) + assert_in_delta(0.125, "0.1_2_5__".to_f, 0.00001) + assert(Float(([1] * 10000).join).infinite?) + assert(!Float(([1] * 10000).join("_")).infinite?) # is it really OK? + assert_raise(ArgumentError) { Float("1.0\x001") } + assert(Float("1e10_00").infinite?) + assert_raise(TypeError) { Float(nil) } + o = Object.new + def o.to_f; inf = 1.0/0.0; inf/inf; end + assert_raise(ArgumentError) { Float(o) } + end + + def test_num2dbl + assert_raise(TypeError) do + 1.0.step(2.0, "0.5") {} + end + assert_raise(TypeError) do + 1.0.step(2.0, nil) {} + end + end + end diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb index 5e0f0a0538..e31fb1880d 100644 --- a/test/ruby/test_integer.rb +++ b/test/ruby/test_integer.rb @@ -185,4 +185,9 @@ class TestInteger < Test::Unit::TestCase assert_equal(-1111_1111_1111_1111_1111_1111_1111_1110, (-1111_1111_1111_1111_1111_1111_1111_1111).round(-1)) assert_equal(Bignum, (-1111_1111_1111_1111_1111_1111_1111_1111).round(-1).class) end + + def test_Integer2 + assert_equal(2 ** 50, Integer(2.0 ** 50)) + assert_raise(TypeError) { Integer(nil) } + end end diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index f4055e7950..df0ec792f3 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -1,4 +1,5 @@ require 'test/unit' +require_relative 'envutil' class TestMethod < Test::Unit::TestCase def setup @@ -10,6 +11,10 @@ class TestMethod < Test::Unit::TestCase $VERBOSE = @verbose end + def ruby(*r, &b) + EnvUtil.rubyexec(*r, &b) + end + def m0() end def m1(a) end def m2(a, b) end @@ -202,4 +207,17 @@ class TestMethod < Test::Unit::TestCase m2 = c2.new.method(:foo) assert_equal("#", m2.inspect) end + + def test_callee_top_level + ruby do |w, r, e| + w.puts "p __callee__" + w.close + assert_equal("nil", r.read.chomp) + assert_match("", e.read.chomp) + end + end + + def test_caller_negative_level + assert_raise(ArgumentError) { caller(-1) } + end end diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 81ba08cf32..8baf15aa56 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -1,9 +1,22 @@ require 'test/unit' require 'pp' +require_relative 'envutil' $m0 = Module.nesting class TestModule < Test::Unit::TestCase + def setup + @verbose = $VERBOSE + $VERBOSE = nil + end + + def teardown + $VERBOSE = @verbose + end + + def ruby(*r, &b) + EnvUtil.rubyexec(*r, &b) + end def test_LT_0 assert_equal true, String < Object @@ -313,4 +326,322 @@ class TestModule < Test::Unit::TestCase assert_instance_of(Module, m) end + def test_freeze + m = Module.new + m.freeze + assert_raise(RuntimeError) do + m.module_eval do + def foo; end + end + end + end + + def test_attr_obsoleted_flag + c = Class.new + c.class_eval do + def initialize + @foo = :foo + @bar = :bar + end + attr :foo, true + attr :bar, false + end + o = c.new + assert_equal(true, o.respond_to?(:foo)) + assert_equal(true, o.respond_to?(:foo=)) + assert_equal(true, o.respond_to?(:bar)) + assert_equal(false, o.respond_to?(:bar=)) + end + + def test_const_get2 + c1 = Class.new + c2 = Class.new(c1) + + eval("c1::Foo = :foo") + assert_equal(:foo, c1::Foo) + assert_equal(:foo, c2::Foo) + assert_equal(:foo, c2.const_get(:Foo)) + assert_raise(NameError) { c2.const_get(:Foo, false) } + + eval("c1::Foo = :foo") + assert_raise(NameError) { c1::Bar } + assert_raise(NameError) { c2::Bar } + assert_raise(NameError) { c2.const_get(:Bar) } + assert_raise(NameError) { c2.const_get(:Bar, false) } + + c1.instance_eval do + def const_missing(x) + x + end + end + + assert_equal(:Bar, c1::Bar) + assert_equal(:Bar, c2::Bar) + assert_equal(:Bar, c2.const_get(:Bar)) + assert_equal(:Bar, c2.const_get(:Bar, false)) + + assert_raise(NameError) { c1.const_get(:foo) } + end + + def test_const_set2 + c1 = Class.new + assert_raise(NameError) { c1.const_set(:foo, :foo) } + end + + def test_const_get3 + c1 = Class.new + assert_raise(NameError) { c1.const_defined?(:foo) } + end + + def test_class_variable_get2 + c = Class.new + c.class_eval { @@foo = :foo } + assert_equal(:foo, c.class_variable_get(:@@foo)) + assert_raise(NameError) { c.class_variable_get(:@@bar) } # c.f. instance_variable_get + assert_raise(NameError) { c.class_variable_get(:foo) } + end + + def test_class_variable_set2 + c = Class.new + c.class_variable_set(:@@foo, :foo) + assert_equal(:foo, c.class_eval { @@foo }) + assert_raise(NameError) { c.class_variable_set(:foo, 1) } + end + + def test_class_variable_defined + c = Class.new + c.class_eval { @@foo = :foo } + assert_equal(true, c.class_variable_defined?(:@@foo)) + assert_equal(false, c.class_variable_defined?(:@@bar)) + assert_raise(NameError) { c.class_variable_defined?(:foo) } + end + + def test_export_method + m = Module.new + assert_raise(NameError) do + m.instance_eval { public(:foo) } + end + end + + def test_attr + ruby do |w, r, e| + w.puts "$VERBOSE = true" + w.puts "c = Class.new" + w.puts "c.instance_eval do" + w.puts " private" + w.puts " attr_reader :foo" + w.puts "end" + w.puts "o = c.new" + w.puts "o.foo rescue p(:ok)" + w.puts "p(o.instance_eval { foo })" + w.close + assert_equal(":ok\nnil", r.read.chomp) + assert_match(/warning: private attribute\?$/, e.read.chomp) + end + + c = Class.new + assert_raise(NameError) do + c.instance_eval { attr_reader :"$" } + end + end + + def test_undef + assert_raise(SecurityError) do + Thread.new do + $SAFE = 4 + Class.instance_eval { undef_method(:foo) } + end.join + end + + c = Class.new + assert_raise(NameError) do + c.instance_eval { undef_method(:foo) } + end + + m = Module.new + assert_raise(NameError) do + m.instance_eval { undef_method(:foo) } + end + + o = Object.new + assert_raise(NameError) do + class << o; self; end.instance_eval { undef_method(:foo) } + end + + %w(object_id __send__ initialize).each do |m| + ruby do |w, r, e| + w.puts "$VERBOSE = false" + w.puts "Class.new.instance_eval { undef_method(:#{m}) }" + w.close + assert_equal("", r.read.chomp) + assert_match(/warning: undefining `#{m}' may cause serious problem$/, e.read.chomp) + end + end + end + + def test_alias + m = Module.new + assert_raise(NameError) do + m.class_eval { alias foo bar } + end + + ruby do |w, r, e| + w.puts "$VERBOSE = true" + w.puts "c = Class.new" + w.puts "c.class_eval do" + w.puts " def foo; 1; end" + w.puts " def bar; 2; end" + w.puts "end" + w.puts "c.class_eval { alias foo bar }" + w.puts "p c.new.foo" + w.close + assert_equal("2", r.read.chomp) + assert_match(/warning: discarding old foo$/, e.read.chomp) + end + end + + def test_mod_constants + Module.const_set(:Foo, :foo) + assert_equal([:Foo], Module.constants(true)) + assert_equal([:Foo], Module.constants(false)) + Module.instance_eval { remove_const(:Foo) } + end + + def test_frozen_class + m = Module.new + m.freeze + assert_raise(RuntimeError) do + m.instance_eval { undef_method(:foo) } + end + + c = Class.new + c.freeze + assert_raise(RuntimeError) do + c.instance_eval { undef_method(:foo) } + end + + o = Object.new + c = class << o; self; end + c.freeze + assert_raise(RuntimeError) do + c.instance_eval { undef_method(:foo) } + end + end + + def test_method_defined + c = Class.new + c.class_eval do + def foo; end + def bar; end + def baz; end + public :foo + protected :bar + private :baz + end + + assert_equal(true, c.public_method_defined?(:foo)) + assert_equal(false, c.public_method_defined?(:bar)) + assert_equal(false, c.public_method_defined?(:baz)) + + assert_equal(false, c.protected_method_defined?(:foo)) + assert_equal(true, c.protected_method_defined?(:bar)) + assert_equal(false, c.protected_method_defined?(:baz)) + + assert_equal(false, c.private_method_defined?(:foo)) + assert_equal(false, c.private_method_defined?(:bar)) + assert_equal(true, c.private_method_defined?(:baz)) + end + + def test_change_visibility_under_safe4 + c = Class.new + c.class_eval do + def foo; end + end + assert_raise(SecurityError) do + Thread.new do + $SAFE = 4 + c.class_eval { private :foo } + end.join + end + end + + def test_top_public_private + ruby do |w, r, e| + w.puts "private" + w.puts "def foo; :foo; end" + w.puts "public" + w.puts "def bar; :bar; end" + w.puts "p self.private_methods.grep(/^foo$|^bar$/)" + w.puts "p self.methods.grep(/^foo$|^bar$/)" + w.close + assert_equal("[:foo]\n[:bar]", r.read.chomp) + assert_equal("", e.read.chomp) + end + end + + def test_append_features + t = nil + m = Module.new + m.module_eval do + def foo; :foo; end + end + class << m; self; end.class_eval do + define_method(:append_features) do |mod| + t = mod + super(mod) + end + end + + m2 = Module.new + m2.module_eval { include(m) } + assert_equal(m2, t) + + o = Object.new + o.extend(m2) + assert_equal(true, o.respond_to?(:foo)) + end + + def test_append_features_raise + m = Module.new + m.module_eval do + def foo; :foo; end + end + class << m; self; end.class_eval do + define_method(:append_features) {|mod| raise } + end + + m2 = Module.new + assert_raise(RuntimeError) do + m2.module_eval { include(m) } + end + + o = Object.new + o.extend(m2) + assert_equal(false, o.respond_to?(:foo)) + end + + def test_append_features_type_error + assert_raise(TypeError) do + Module.new.instance_eval { append_features(1) } + end + end + + def test_included + m = Module.new + m.module_eval do + def foo; :foo; end + end + class << m; self; end.class_eval do + define_method(:included) {|mod| raise } + end + + m2 = Module.new + assert_raise(RuntimeError) do + m2.module_eval { include(m) } + end + + o = Object.new + o.extend(m2) + assert_equal(true, o.respond_to?(:foo)) + end end diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb new file mode 100644 index 0000000000..7878bf5597 --- /dev/null +++ b/test/ruby/test_object.rb @@ -0,0 +1,339 @@ +require 'test/unit' +require_relative 'envutil' + +class TestObject < Test::Unit::TestCase + def setup + @verbose = $VERBOSE + $VERBOSE = nil + end + + def teardown + $VERBOSE = @verbose + end + + def ruby(*r, &b) + EnvUtil.rubyexec(*r, &b) + end + + def test_dup + assert_raise(TypeError) { 1.dup } + assert_raise(TypeError) { true.dup } + assert_raise(TypeError) { nil.dup } + + assert_raise(TypeError) do + Object.new.instance_eval { initialize_copy(1) } + end + end + + def test_instance_of + assert_raise(TypeError) { 1.instance_of?(1) } + end + + def test_kind_of + assert_raise(TypeError) { 1.kind_of?(1) } + end + + def test_taint_frozen_obj + o = Object.new + o.freeze + assert_raise(RuntimeError) { o.taint } + + o = Object.new + o.taint + o.freeze + assert_raise(RuntimeError) { o.untaint } + end + + def test_freeze_under_safe_4 + o = Object.new + assert_raise(SecurityError) do + Thread.new do + $SAFE = 4 + o.freeze + end.join + end + end + + def test_freeze_immediate + assert_equal(false, 1.frozen?) + 1.freeze + assert_equal(true, 1.frozen?) + assert_equal(false, 2.frozen?) + end + + def test_nil_to_f + assert_equal(0.0, nil.to_f) + end + + def test_not + assert_equal(false, Object.new.send(:!)) + assert_equal(true, nil.send(:!)) + end + + def test_true_and + assert_equal(true, true & true) + assert_equal(true, true & 1) + assert_equal(false, true & false) + assert_equal(false, true & nil) + end + + def test_true_or + assert_equal(true, true | true) + assert_equal(true, true | 1) + assert_equal(true, true | false) + assert_equal(true, true | nil) + end + + def test_true_xor + assert_equal(false, true ^ true) + assert_equal(false, true ^ 1) + assert_equal(true, true ^ false) + assert_equal(true, true ^ nil) + end + + def test_false_and + assert_equal(false, false & true) + assert_equal(false, false & 1) + assert_equal(false, false & false) + assert_equal(false, false & nil) + end + + def test_false_or + assert_equal(true, false | true) + assert_equal(true, false | 1) + assert_equal(false, false | false) + assert_equal(false, false | nil) + end + + def test_false_xor + assert_equal(true, false ^ true) + assert_equal(true, false ^ 1) + assert_equal(false, false ^ false) + assert_equal(false, false ^ nil) + end + + def test_methods + o = Object.new + a1 = o.methods + a2 = o.methods(false) + + def o.foo; end + + assert_equal([:foo], o.methods(true) - a1) + assert_equal([:foo], o.methods(false) - a2) + end + + def test_methods2 + c0 = Class.new + c1 = Class.new(c0) + c1.module_eval do + public ; def foo; end + protected; def bar; end + private ; def baz; end + end + c2 = Class.new(c1) + c2.module_eval do + public ; def foo2; end + protected; def bar2; end + private ; def baz2; end + end + + o0 = c0.new + o2 = c2.new + + assert_equal([:baz, :baz2], (o2.private_methods - o0.private_methods).sort) + assert_equal([:baz2], (o2.private_methods(false) - o0.private_methods(false)).sort) + + assert_equal([:bar, :bar2], (o2.protected_methods - o0.protected_methods).sort) + assert_equal([:bar2], (o2.protected_methods(false) - o0.protected_methods(false)).sort) + + assert_equal([:foo, :foo2], (o2.public_methods - o0.public_methods).sort) + assert_equal([:foo2], (o2.public_methods(false) - o0.public_methods(false)).sort) + end + + def test_instance_variable_get + o = Object.new + o.instance_eval { @foo = :foo } + assert_equal(:foo, o.instance_variable_get(:@foo)) + assert_equal(nil, o.instance_variable_get(:@bar)) + assert_raise(NameError) { o.instance_variable_get(:foo) } + end + + def test_instance_variable_set + o = Object.new + o.instance_variable_set(:@foo, :foo) + assert_equal(:foo, o.instance_eval { @foo }) + assert_raise(NameError) { o.instance_variable_set(:foo, 1) } + end + + def test_instance_variable_defined + o = Object.new + o.instance_eval { @foo = :foo } + assert_equal(true, o.instance_variable_defined?(:@foo)) + assert_equal(false, o.instance_variable_defined?(:@bar)) + assert_raise(NameError) { o.instance_variable_defined?(:foo) } + end + + def test_convert_type + o = Object.new + def o.to_s; 1; end + assert_raise(TypeError) { String(o) } + end + + def test_check_convert_type + o = Object.new + def o.to_a; 1; end + assert_raise(TypeError) { Array(o) } + end + + def test_to_integer + o = Object.new + def o.to_i; nil; end + assert_raise(TypeError) { Integer(o) } + end + + class MyInteger + def initialize(n); @num = n; end + def to_int; @num; end + def <=>(n); @num <=> n.to_int; end + def <=(n); @num <= n.to_int; end + def +(n); MyInteger.new(@num + n.to_int); end + end + + def test_check_to_integer + o1 = MyInteger.new(1) + o9 = MyInteger.new(9) + n = 0 + Range.new(o1, o9).step(2) {|x| n += x.to_int } + assert_equal(1+3+5+7+9, n) + end + + def test_add_method_under_safe4 + o = Object.new + assert_raise(SecurityError) do + Thread.new do + $SAFE = 4 + def o.foo + end + end.join + end + end + + def test_redefine_method_under_verbose + ruby do |w, r, e| + w.puts "$VERBOSE = true" + w.puts "o = Object.new" + w.puts "def o.foo; 1; end" + w.puts "def o.foo; 2; end" + w.puts "p o.foo" + w.close + assert_equal("2", r.read.chomp) + assert_match(/warning: method redefined; discarding old foo$/, e.read.chomp) + end + end + + def test_redefine_method_which_may_case_serious_problem + ruby do |w, r, e| + w.puts "$VERBOSE = false" + w.puts "def (Object.new).object_id; end" + w.close + assert_equal("", r.read.chomp) + assert_match(/warning: redefining `object_id' may cause serious problem$/, e.read.chomp) + end + + ruby do |w, r, e| + w.puts "$VERBOSE = false" + w.puts "def (Object.new).__send__; end" + w.close + assert_equal("", r.read.chomp) + assert_match(/warning: redefining `__send__' may cause serious problem$/, e.read.chomp) + end + end + + def test_remove_method + assert_raise(SecurityError) do + Thread.new do + $SAFE = 4 + Object.instance_eval { remove_method(:foo) } + end.join + end + + assert_raise(SecurityError) do + Thread.new do + $SAFE = 4 + Class.instance_eval { remove_method(:foo) } + end.join + end + + c = Class.new + c.freeze + assert_raise(RuntimeError) do + c.instance_eval { remove_method(:foo) } + end + + %w(object_id __send__ initialize).each do |m| + ruby do |w, r, e| + w.puts "$VERBOSE = false" + w.puts "begin" + w.puts " Class.new.instance_eval { remove_method(:#{m}) }" + w.puts "rescue NameError" + w.puts " p :ok" + w.puts "end" + w.close + assert_equal(":ok", r.read.chomp) + assert_match(/warning: removing `#{m}' may cause serious problem$/, e.read.chomp) + end + end + end + + def test_method_missing + assert_raise(ArgumentError) do + 1.instance_eval { method_missing } + end + + c = Class.new + c.class_eval do + protected + def foo; end + end + assert_raise(NoMethodError) do + c.new.foo + end + + assert_raise(NoMethodError) do + 1.instance_eval { method_missing(:method_missing) } + end + end + + def test_send_with_no_arguments + assert_raise(ArgumentError) { 1.send } + end + + def test_specific_eval_with_wrong_arguments + assert_raise(ArgumentError) do + 1.instance_eval("foo") { foo } + end + + assert_raise(ArgumentError) do + 1.instance_eval + end + + assert_raise(ArgumentError) do + 1.instance_eval("", 1, 1, 1) + end + end + + def test_instance_exec + x = 1.instance_exec(42) {|a| self + a } + assert_equal(43, x) + + x = "foo".instance_exec("bar") {|a| self + a } + assert_equal("foobar", x) + end + + def test_extend + assert_raise(ArgumentError) do + 1.extend + end + end +end diff --git a/test/ruby/test_trace.rb b/test/ruby/test_trace.rb index 6adfe0bf64..48294c9694 100644 --- a/test/ruby/test_trace.rb +++ b/test/ruby/test_trace.rb @@ -18,4 +18,32 @@ class TestTrace < Test::Unit::TestCase untrace_var :$x end + + def test_trace_tainted_proc + $x = 1234 + s = proc { $y = :foo } + trace_var :$x, s + s.taint + $x = 42 + assert_equal(:foo, $y) + ensure + untrace_var :$x + end + + def test_trace_proc_that_raises_exception + $x = 1234 + trace_var :$x, proc { raise } + assert_raise(RuntimeError) { $x = 42 } + ensure + untrace_var :$x + end + + def test_trace_string + $x = 1234 + trace_var :$x, "$y = :bar" + $x = 42 + assert_equal(:bar, $y) + ensure + untrace_var :$x + end end diff --git a/test/ruby/test_variable.rb b/test/ruby/test_variable.rb index 601fc21c74..bfa5977f62 100644 --- a/test/ruby/test_variable.rb +++ b/test/ruby/test_variable.rb @@ -66,4 +66,13 @@ class TestVariable < Test::Unit::TestCase assert_equal([:x, :y], local_variables.sort) end.call end + + def test_local_variables3 + x = 1 + proc do |y| + 1.times do |z| + assert_equal([:x, :y, :z], local_variables.sort) + end + end.call + end end -- cgit v1.2.3