summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-02 11:34:19 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-02 11:34:19 +0000
commit19ddfc2483bb82cfb241a58d4b25956f7b79d1ad (patch)
treec5eecb286e12abe5d5201d4fe2c6bee9efdf5a31 /test/ruby
parent319088e9c7ae9836efd242592ea80c9794a45002 (diff)
* eval.c (rb_mod_using): new method Module#using. [experimental]
* eval.c (rb_mod_refine): new method Module#refine. [experimental] * eval.c (f_using): new method Kernel#using. [experimental] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36596 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_fiber.rb5
-rw-r--r--test/ruby/test_refinement.rb304
-rw-r--r--test/ruby/test_thread.rb5
3 files changed, 306 insertions, 8 deletions
diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb
index 9bac234252..44bdbfc2f7 100644
--- a/test/ruby/test_fiber.rb
+++ b/test/ruby/test_fiber.rb
@@ -216,10 +216,7 @@ class TestFiber < Test::Unit::TestCase
def test_no_valid_cfp
bug5083 = '[ruby-dev:44208]'
- error = assert_raise(RuntimeError) do
- Fiber.new(&Module.method(:nesting)).resume
- end
- assert_equal("Can't call on top of Fiber or Thread", error.message, bug5083)
+ assert_equal([], Fiber.new(&Module.method(:nesting)).resume)
error = assert_raise(RuntimeError) do
Fiber.new(&Module.method(:undef_method)).resume(:to_s)
end
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
new file mode 100644
index 0000000000..65789899c5
--- /dev/null
+++ b/test/ruby/test_refinement.rb
@@ -0,0 +1,304 @@
+require 'test/unit'
+
+class TestRefinement < Test::Unit::TestCase
+ class Foo
+ def x
+ return "Foo#x"
+ end
+
+ def y
+ return "Foo#y"
+ end
+
+ def call_x
+ return x
+ end
+ end
+
+ module FooExt
+ refine Foo do
+ def x
+ return "FooExt#x"
+ end
+
+ def y
+ return "FooExt#y " + super
+ end
+
+ def z
+ return "FooExt#z"
+ end
+ end
+ end
+
+ module FooExt2
+ refine Foo do
+ def x
+ return "FooExt2#x"
+ end
+
+ def y
+ return "FooExt2#y " + super
+ end
+
+ def z
+ return "FooExt2#z"
+ end
+ end
+ end
+
+ class FooSub < Foo
+ def x
+ return "FooSub#x"
+ end
+
+ def y
+ return "FooSub#y " + super
+ end
+ end
+
+ class FooExtClient
+ using FooExt
+
+ def self.invoke_x_on(foo)
+ return foo.x
+ end
+
+ def self.invoke_y_on(foo)
+ return foo.y
+ end
+
+ def self.invoke_z_on(foo)
+ return foo.z
+ end
+
+ def self.invoke_call_x_on(foo)
+ return foo.call_x
+ end
+ end
+
+ class FooExtClient2
+ using FooExt
+ using FooExt2
+
+ def self.invoke_y_on(foo)
+ return foo.y
+ end
+ end
+
+ def test_override
+ foo = Foo.new
+ assert_equal("Foo#x", foo.x)
+ assert_equal("FooExt#x", FooExtClient.invoke_x_on(foo))
+ assert_equal("Foo#x", foo.x)
+ end
+
+ def test_super
+ foo = Foo.new
+ assert_equal("Foo#y", foo.y)
+ assert_equal("FooExt#y Foo#y", FooExtClient.invoke_y_on(foo))
+ assert_equal("Foo#y", foo.y)
+ end
+
+ def test_super_chain
+ foo = Foo.new
+ assert_equal("Foo#y", foo.y)
+ assert_equal("FooExt2#y FooExt#y Foo#y", FooExtClient2.invoke_y_on(foo))
+ assert_equal("Foo#y", foo.y)
+ end
+
+ def test_new_method
+ foo = Foo.new
+ assert_raise(NoMethodError) { foo.z }
+ assert_equal("FooExt#z", FooExtClient.invoke_z_on(foo))
+ assert_raise(NoMethodError) { foo.z }
+ end
+
+ def test_no_local_rebinding
+ foo = Foo.new
+ assert_equal("Foo#x", foo.call_x)
+ assert_equal("Foo#x", FooExtClient.invoke_call_x_on(foo))
+ assert_equal("Foo#x", foo.call_x)
+ end
+
+ def test_subclass_is_prior
+ sub = FooSub.new
+ assert_equal("FooSub#x", sub.x)
+ assert_equal("FooSub#x", FooExtClient.invoke_x_on(sub))
+ assert_equal("FooSub#x", sub.x)
+ end
+
+ def test_super_in_subclass
+ sub = FooSub.new
+ assert_equal("FooSub#y Foo#y", sub.y)
+ # not "FooSub#y FooExt#y Foo#y"
+ assert_equal("FooSub#y Foo#y", FooExtClient.invoke_y_on(sub))
+ assert_equal("FooSub#y Foo#y", sub.y)
+ end
+
+ def test_new_method_on_subclass
+ sub = FooSub.new
+ assert_raise(NoMethodError) { sub.z }
+ assert_equal("FooExt#z", FooExtClient.invoke_z_on(sub))
+ assert_raise(NoMethodError) { sub.z }
+ end
+
+ def test_module_eval
+ foo = Foo.new
+ assert_equal("Foo#x", foo.x)
+ assert_equal("FooExt#x", FooExt.module_eval { foo.x })
+ assert_equal("Foo#x", foo.x)
+ end
+
+ def test_instance_eval
+ foo = Foo.new
+ ext_client = FooExtClient.new
+ assert_equal("Foo#x", foo.x)
+ assert_equal("FooExt#x", ext_client.instance_eval { foo.x })
+ assert_equal("Foo#x", foo.x)
+ end
+
+ def test_override_builtin_method
+ m = Module.new {
+ refine Fixnum do
+ def /(other) quo(other) end
+ end
+ }
+ assert_equal(0, 1 / 2)
+ assert_equal(Rational(1, 2), m.module_eval { 1 / 2 })
+ assert_equal(0, 1 / 2)
+ end
+
+ def test_return_value_of_refine
+ mod = nil
+ result = nil
+ m = Module.new {
+ result = refine(Object) {
+ mod = self
+ }
+ }
+ assert_equal mod, result
+ end
+
+ def test_refine_same_class_twice
+ result1 = nil
+ result2 = nil
+ result3 = nil
+ m = Module.new {
+ result1 = refine(Fixnum) {
+ def foo; return "foo" end
+ }
+ result2 = refine(Fixnum) {
+ def bar; return "bar" end
+ }
+ result3 = refine(String) {
+ def baz; return "baz" end
+ }
+ }
+ assert_equal("foo", m.module_eval { 1.foo })
+ assert_equal("bar", m.module_eval { 1.bar })
+ assert_equal(result1, result2)
+ assert_not_equal(result1, result3)
+ end
+
+ def test_respond_to?
+ m = Module.new {
+ refine Fixnum do
+ def foo; "foo"; end
+ end
+ }
+ assert_equal(false, 1.respond_to?(:foo))
+ assert_equal(true, m.module_eval { 1.respond_to?(:foo) })
+ assert_equal(false, 1.respond_to?(:foo))
+ end
+
+ def test_builtin_method_no_local_rebinding
+ m = Module.new {
+ refine String do
+ def <=>(other) return 0 end
+ end
+ }
+ assert_equal(false, m.module_eval { "1" >= "2" })
+
+ m2 = Module.new {
+ refine Array do
+ def each
+ super do |i|
+ yield 2 * i
+ end
+ end
+ end
+ }
+ a = [1, 2, 3]
+ assert_equal(1, m2.module_eval { a.min })
+ end
+
+ def test_module_inclusion
+ m1 = Module.new {
+ def foo
+ "m1#foo"
+ end
+
+ def bar
+ "m1#bar"
+ end
+ }
+ m2 = Module.new {
+ def bar
+ "m2#bar"
+ end
+
+ def baz
+ "m2#baz"
+ end
+ }
+ m3 = Module.new {
+ def baz
+ "m3#baz"
+ end
+ }
+ include_proc = Proc.new {
+ include m3, m2
+ }
+ m = Module.new {
+ refine String do
+ include m1
+ module_eval(&include_proc)
+
+ def call_foo
+ foo
+ end
+
+ def call_bar
+ bar
+ end
+
+ def call_baz
+ baz
+ end
+ end
+
+ def self.call_foo(s)
+ s.foo
+ end
+
+ def self.call_bar(s)
+ s.bar
+ end
+
+ def self.call_baz(s)
+ s.baz
+ end
+ }
+ assert_equal("m1#foo", m.module_eval { "abc".foo })
+ assert_equal("m2#bar", m.module_eval { "abc".bar })
+ assert_equal("m3#baz", m.module_eval { "abc".baz })
+ assert_equal("m1#foo", m.module_eval { "abc".call_foo })
+ assert_equal("m2#bar", m.module_eval { "abc".call_bar })
+ assert_equal("m3#baz", m.module_eval { "abc".call_baz })
+ assert_equal("m1#foo", m.call_foo("abc"))
+ assert_equal("m2#bar", m.call_bar("abc"))
+ assert_equal("m3#baz", m.call_baz("abc"))
+ end
+end
+
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb
index 523cad4242..c8081b46b8 100644
--- a/test/ruby/test_thread.rb
+++ b/test/ruby/test_thread.rb
@@ -606,10 +606,7 @@ class TestThread < Test::Unit::TestCase
def test_no_valid_cfp
skip 'with win32ole, cannot run this testcase because win32ole redefines Thread#intialize' if defined?(WIN32OLE)
bug5083 = '[ruby-dev:44208]'
- error = assert_raise(RuntimeError) do
- Thread.new(&Module.method(:nesting)).join
- end
- assert_equal("Can't call on top of Fiber or Thread", error.message, bug5083)
+ assert_equal([], Thread.new(&Module.method(:nesting)).value)
error = assert_raise(RuntimeError) do
Thread.new(:to_s, &Module.method(:undef_method)).join
end