зеркало из https://github.com/github/ruby.git
* eval.c (eval): allow to eval in a binding that has a singleton method.
[ruby-dev:33763] * test/ruby/test_proc.rb: add tests to achieve over 70% test coverage of time.c. * test/ruby/test_method.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15462 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
70f25096c0
Коммит
a707f6249f
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Thu Feb 14 00:02:19 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
||||
|
||||
* eval.c (eval): allow to eval in a binding that has a singleton method.
|
||||
[ruby-dev:33763]
|
||||
|
||||
* test/ruby/test_proc.rb: add tests to achieve over 70% test coverage
|
||||
of time.c.
|
||||
|
||||
* test/ruby/test_method.rb: ditto.
|
||||
|
||||
Wed Feb 13 22:46:36 2008 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* lib/pathname.rb (Pathname#sub_ext): new method. [ruby-list:44608]
|
||||
|
|
2
eval.c
2
eval.c
|
@ -1700,7 +1700,7 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
|
|||
volatile VALUE iseqval;
|
||||
|
||||
if (scope != Qnil) {
|
||||
if (CLASS_OF(scope) == rb_cBinding) {
|
||||
if (rb_obj_is_kind_of(scope, rb_cBinding)) {
|
||||
GetBindingPtr(scope, bind);
|
||||
envval = bind->env;
|
||||
stored_cref_stack = bind->cref_stack;
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
require 'test/unit'
|
||||
|
||||
class TestMethod < Test::Unit::TestCase
|
||||
def setup
|
||||
@verbose = $VERBOSE
|
||||
$VERBOSE = nil
|
||||
end
|
||||
|
||||
def teardown
|
||||
$VERBOSE = @verbose
|
||||
end
|
||||
|
||||
def m0() end
|
||||
def m1(a) end
|
||||
def m2(a, b) end
|
||||
|
@ -52,4 +61,143 @@ class TestMethod < Test::Unit::TestCase
|
|||
assert_equal(:m, Class.new {define_method(:m) {tap{return __method__}}}.new.m)
|
||||
assert_nil(eval("class TestCallee; __method__; end"))
|
||||
end
|
||||
|
||||
def test_body
|
||||
o = Object.new
|
||||
def o.foo; end
|
||||
assert_nothing_raised { VM::InstructionSequence.disasm(o.method(:foo)) }
|
||||
end
|
||||
|
||||
def test_new
|
||||
c1 = Class.new
|
||||
c1.class_eval { def foo; :foo; end }
|
||||
c2 = Class.new(c1)
|
||||
c2.class_eval { private :foo }
|
||||
o = c2.new
|
||||
o.extend(Module.new)
|
||||
assert_raise(NameError) { o.method(:bar) }
|
||||
assert_raise(NameError) { o.public_method(:foo) }
|
||||
assert_equal(:foo, o.method(:foo).call)
|
||||
end
|
||||
|
||||
def test_eq
|
||||
o = Object.new
|
||||
class << o
|
||||
def foo; end
|
||||
alias bar foo
|
||||
def baz; end
|
||||
end
|
||||
assert_not_equal(o.method(:foo), nil)
|
||||
m = o.method(:foo)
|
||||
def m.foo; end
|
||||
assert_not_equal(o.method(:foo), m)
|
||||
assert_equal(o.method(:foo), o.method(:foo))
|
||||
assert_equal(o.method(:foo), o.method(:bar))
|
||||
assert_not_equal(o.method(:foo), o.method(:baz))
|
||||
end
|
||||
|
||||
def test_hash
|
||||
o = Object.new
|
||||
def o.foo; end
|
||||
assert_kind_of(Integer, o.method(:foo).hash)
|
||||
end
|
||||
|
||||
def test_receiver_name_owner
|
||||
o = Object.new
|
||||
def o.foo; end
|
||||
m = o.method(:foo)
|
||||
assert_equal(o, m.receiver)
|
||||
assert_equal("foo", m.name)
|
||||
assert_equal(class << o; self; end, m.owner)
|
||||
end
|
||||
|
||||
def test_instance_method
|
||||
c = Class.new
|
||||
c.class_eval do
|
||||
def foo; :foo; end
|
||||
private :foo
|
||||
end
|
||||
o = c.new
|
||||
o.method(:foo).unbind
|
||||
assert_raise(NoMethodError) { o.foo }
|
||||
c.instance_method(:foo).bind(o)
|
||||
assert_equal(:foo, o.instance_eval { foo })
|
||||
assert_raise(NameError) { c.public_instance_method(:foo) }
|
||||
def o.bar; end
|
||||
m = o.method(:bar).unbind
|
||||
assert_raise(TypeError) { m.bind(Object.new) }
|
||||
end
|
||||
|
||||
def test_define_method
|
||||
c = Class.new
|
||||
c.class_eval { def foo; :foo; end }
|
||||
o = c.new
|
||||
def o.bar; :bar; end
|
||||
assert_raise(TypeError) do
|
||||
c.class_eval { define_method(:foo, :foo) }
|
||||
end
|
||||
assert_raise(ArgumentError) do
|
||||
c.class_eval { define_method }
|
||||
end
|
||||
c2 = Class.new(c)
|
||||
c2.class_eval { define_method(:baz, o.method(:foo)) }
|
||||
assert_equal(:foo, c2.new.baz)
|
||||
assert_raise(TypeError) do
|
||||
Class.new.class_eval { define_method(:foo, o.method(:foo)) }
|
||||
end
|
||||
assert_raise(TypeError) do
|
||||
Class.new.class_eval { define_method(:bar, o.method(:bar)) }
|
||||
end
|
||||
|
||||
o = Object.new
|
||||
def o.foo(c)
|
||||
c.class_eval { define_method(:foo) }
|
||||
end
|
||||
c = Class.new
|
||||
o.foo(c) { :foo }
|
||||
assert_equal(:foo, c.new.foo)
|
||||
|
||||
o = Object.new
|
||||
o.instance_eval { define_singleton_method(:foo) { :foo } }
|
||||
assert_equal(:foo, o.foo)
|
||||
end
|
||||
|
||||
def test_clone
|
||||
o = Object.new
|
||||
def o.foo; :foo; end
|
||||
m = o.method(:foo)
|
||||
def m.bar; :bar; end
|
||||
assert_equal(:foo, m.clone.call)
|
||||
assert_equal(:bar, m.clone.bar)
|
||||
end
|
||||
|
||||
def test_call
|
||||
o = Object.new
|
||||
def o.foo; p 1; end
|
||||
def o.bar(x); x; end
|
||||
m = o.method(:foo)
|
||||
m.taint
|
||||
assert_raise(SecurityError) { m.call }
|
||||
end
|
||||
|
||||
def test_inspect
|
||||
o = Object.new
|
||||
def o.foo; end
|
||||
m = o.method(:foo)
|
||||
assert_equal("#<Method: #{ o.inspect }.foo>", m.inspect)
|
||||
m = o.method(:foo)
|
||||
assert_equal("#<UnboundMethod: #{ class << o; self; end.inspect }#foo>", m.unbind.inspect)
|
||||
|
||||
c = Class.new
|
||||
c.class_eval { def foo; end; }
|
||||
m = c.new.method(:foo)
|
||||
assert_equal("#<Method: #{ c.inspect }#foo>", m.inspect)
|
||||
m = c.instance_method(:foo)
|
||||
assert_equal("#<UnboundMethod: #{ c.inspect }#foo>", m.inspect)
|
||||
|
||||
c2 = Class.new(c)
|
||||
c2.class_eval { private :foo }
|
||||
m2 = c2.new.method(:foo)
|
||||
assert_equal("#<Method: #{ c2.inspect }(#{ c.inspect })#foo>", m2.inspect)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
require 'test/unit'
|
||||
|
||||
class TestProc < Test::Unit::TestCase
|
||||
def setup
|
||||
@verbose = $VERBOSE
|
||||
$VERBOSE = nil
|
||||
end
|
||||
|
||||
def teardown
|
||||
$VERBOSE = @verbose
|
||||
end
|
||||
|
||||
def test_proc
|
||||
p1 = proc{|i| i}
|
||||
assert_equal(2, p1.call(2))
|
||||
|
@ -200,4 +209,92 @@ class TestProc < Test::Unit::TestCase
|
|||
|
||||
assert_equal(fib, [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89])
|
||||
end
|
||||
|
||||
def test_dup_clone
|
||||
b = proc {|x| x + "bar" }
|
||||
class << b; attr_accessor :foo; end
|
||||
|
||||
bd = b.dup
|
||||
assert_equal("foobar", bd.call("foo"))
|
||||
assert_raise(NoMethodError) { bd.foo = :foo }
|
||||
assert_raise(NoMethodError) { bd.foo }
|
||||
|
||||
bc = b.clone
|
||||
assert_equal("foobar", bc.call("foo"))
|
||||
bc.foo = :foo
|
||||
assert_equal(:foo, bc.foo)
|
||||
end
|
||||
|
||||
def test_binding
|
||||
b = proc {|x, y, z| proc {}.binding }.call(1, 2, 3)
|
||||
class << b; attr_accessor :foo; end
|
||||
|
||||
bd = b.dup
|
||||
assert_equal([1, 2, 3], bd.eval("[x, y, z]"))
|
||||
assert_raise(NoMethodError) { bd.foo = :foo }
|
||||
assert_raise(NoMethodError) { bd.foo }
|
||||
|
||||
bc = b.clone
|
||||
assert_equal([1, 2, 3], bc.eval("[x, y, z]"))
|
||||
bc.foo = :foo
|
||||
assert_equal(:foo, bc.foo)
|
||||
|
||||
b = nil
|
||||
1.times { x, y, z = 1, 2, 3; b = binding }
|
||||
assert_equal([1, 2, 3], b.eval("[x, y, z]"))
|
||||
end
|
||||
|
||||
def test_proc_lambda
|
||||
assert_raise(ArgumentError) { proc }
|
||||
assert_raise(ArgumentError) { lambda }
|
||||
|
||||
o = Object.new
|
||||
def o.foo
|
||||
b = nil
|
||||
1.times { b = lambda }
|
||||
b
|
||||
end
|
||||
assert_equal(:foo, o.foo { :foo }.call)
|
||||
|
||||
def o.foo(&b)
|
||||
b = nil
|
||||
1.times { b = lambda }
|
||||
b
|
||||
end
|
||||
assert_equal(:foo, o.foo { :foo }.call)
|
||||
end
|
||||
|
||||
def test_arity2
|
||||
assert_equal(0, method(:proc).to_proc.arity)
|
||||
assert_equal(-1, proc {}.curry.arity)
|
||||
end
|
||||
|
||||
def test_proc_location
|
||||
t = Thread.new { sleep }
|
||||
assert_raise(ThreadError) { t.instance_eval { initialize { } } }
|
||||
t.kill
|
||||
end
|
||||
|
||||
def test_eq2
|
||||
b1 = proc { }
|
||||
b2 = b1.dup
|
||||
assert(b1 == b2)
|
||||
end
|
||||
|
||||
def test_to_proc
|
||||
b = proc { :foo }
|
||||
assert_equal(:foo, b.to_proc.call)
|
||||
end
|
||||
|
||||
def test_localjump_error
|
||||
o = Object.new
|
||||
def foo; yield; end
|
||||
exc = foo rescue $!
|
||||
assert_nil(exc.exit_value)
|
||||
assert_equal(:noreason, exc.reason)
|
||||
end
|
||||
|
||||
def test_binding2
|
||||
assert_raise(ArgumentError) { proc {}.curry.binding }
|
||||
end
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче