summaryrefslogtreecommitdiff
path: root/test/ruby/test_yield.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_yield.rb')
-rw-r--r--test/ruby/test_yield.rb113
1 files changed, 100 insertions, 13 deletions
diff --git a/test/ruby/test_yield.rb b/test/ruby/test_yield.rb
index 3ae6881b87..e7e65fce9e 100644
--- a/test/ruby/test_yield.rb
+++ b/test/ruby/test_yield.rb
@@ -1,4 +1,6 @@
+# frozen_string_literal: false
require 'test/unit'
+require 'stringio'
class TestRubyYield < Test::Unit::TestCase
@@ -64,9 +66,28 @@ class TestRubyYield < Test::Unit::TestCase
}
end
+ def test_with_enum
+ obj = Object.new
+ def obj.each
+ yield(*[])
+ end
+ obj.each{|*v| assert_equal([], [], '[ruby-dev:32392]')}
+ obj.to_enum.each{|*v| assert_equal([], [], '[ruby-dev:32392]')}
+ end
+
+ def block_args_unleashed
+ yield(1,2,3,4,5)
+ end
+
+ def test_block_args_unleashed
+ r = block_args_unleashed {|a,b=1,*c,d,e|
+ [a,b,c,d,e]
+ }
+ assert_equal([1,2,[3],4,5], r, "[ruby-core:19485]")
+ end
end
-require 'sentence'
+require_relative 'sentence'
class TestRubyYieldGen < Test::Unit::TestCase
Syntax = {
:exp => [["0"],
@@ -155,7 +176,8 @@ class TestRubyYieldGen < Test::Unit::TestCase
:block_arg => [['&', :arg]],
#:test => [['def m() yield', :command_args_noblock, ' end; r = m {', :block_param_def, 'vars', '}; undef m; r']]
:test_proc => [['def m() yield', :command_args_noblock, ' end; r = m {', :block_param_def, 'vars', '}; undef m; r']],
- :test_lambda => [['def m() yield', :command_args_noblock, ' end; r = m(&lambda {', :block_param_def, 'vars', '}); undef m; r']]
+ :test_lambda => [['def m() yield', :command_args_noblock, ' end; r = m(&lambda {', :block_param_def, 'vars', '}); undef m; r']],
+ :test_enum => [['o = Object.new; def o.each() yield', :command_args_noblock, ' end; r1 = r2 = nil; o.each {|*x| r1 = x }; o.to_enum.each {|*x| r2 = x }; [r1, r2]']]
}
def rename_var(obj)
@@ -189,8 +211,8 @@ class TestRubyYieldGen < Test::Unit::TestCase
if args.last == []
args = args[0...-1]
end
- code = "emu_return_args #{args.map {|a| a.join('') }.join(",")}"
- eval code
+ code = "emu_return_args(#{args.map {|a| a.join('') }.join(",")})"
+ eval code, nil, 'generated_code_in_emu_eval_args'
end
def emu_bind_single(arg, param, result_binding)
@@ -304,35 +326,100 @@ class TestRubyYieldGen < Test::Unit::TestCase
}
end
+ def disable_stderr
+ begin
+ save_stderr = $stderr
+ $stderr = StringIO.new
+ yield
+ ensure
+ $stderr = save_stderr
+ end
+ end
+
def check_nofork(t, islambda=false)
t, vars = rename_var(t)
t = t.subst('vars') { " [#{vars.join(",")}]" }
emu_values = emu(t, vars, islambda)
s = t.to_s
+ o = Object.new
#print "#{s}\t\t"
#STDOUT.flush
- begin
- eval_values = eval(s)
- rescue ArgumentError
- eval_values = ArgumentError
- end
+ eval_values = disable_stderr {
+ begin
+ o.instance_eval(s, 'generated_code_in_check_nofork')
+ rescue ArgumentError
+ ArgumentError
+ end
+ }
#success = emu_values == eval_values ? 'succ' : 'fail'
#puts "eval:#{vs_ev.inspect[1...-1].delete(' ')}\temu:#{vs_emu.inspect[1...-1].delete(' ')}\t#{success}"
assert_equal(emu_values, eval_values, s)
end
+ def assert_all_sentences(syntax, *args)
+ syntax = Sentence.expand_syntax(syntax)
+ all_assertions do |a|
+ Sentence.each(syntax, *args) {|t|
+ a.for(t) {yield t}
+ }
+ end
+ end
+
def test_yield
- syntax = Sentence.expand_syntax(Syntax)
- Sentence.each(syntax, :test_proc, 4) {|t|
+ assert_all_sentences(Syntax, :test_proc, 4) {|t|
check_nofork(t)
}
end
def test_yield_lambda
- syntax = Sentence.expand_syntax(Syntax)
- Sentence.each(syntax, :test_lambda, 4) {|t|
+ assert_all_sentences(Syntax, :test_lambda, 4) {|t|
check_nofork(t, true)
}
end
+ def test_yield_enum
+ assert_all_sentences(Syntax, :test_enum, 4) {|t|
+ code = t.to_s
+ r1, r2 = disable_stderr {
+ eval(code, nil, 'generated_code_in_test_yield_enum')
+ }
+ assert_equal(r1, r2, "#{t}")
+ }
+ end
+
+ def test_block_with_mock
+ y = Object.new
+ def y.s(a)
+ yield(a)
+ end
+ m = Object.new
+ def m.method_missing(*a)
+ super
+ end
+ assert_equal [m, nil], y.s(m){|a,b|[a,b]}
+ end
+
+ def test_block_cached_argc
+ # [Bug #11451]
+ assert_ruby_status([], <<-"end;")
+ class Yielder
+ def each
+ yield :x, :y, :z
+ end
+ end
+ class Getter1
+ include Enumerable
+ def each(&block)
+ Yielder.new.each(&block)
+ end
+ end
+ class Getter2
+ include Enumerable
+ def each
+ Yielder.new.each { |a, b, c, d| yield(a) }
+ end
+ end
+ Getter1.new.map{Getter2.new.each{|x|}}
+ end;
+ end
end