diff options
Diffstat (limited to 'test/ruby/test_lambda.rb')
| -rw-r--r-- | test/ruby/test_lambda.rb | 127 |
1 files changed, 99 insertions, 28 deletions
diff --git a/test/ruby/test_lambda.rb b/test/ruby/test_lambda.rb index b12fcf8834..8e460475c0 100644 --- a/test/ruby/test_lambda.rb +++ b/test/ruby/test_lambda.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: false require 'test/unit' class TestLambdaParameters < Test::Unit::TestCase @@ -30,8 +31,10 @@ class TestLambdaParameters < Test::Unit::TestCase bug9605 = '[ruby-core:61468] [Bug #9605]' assert_nothing_raised(ArgumentError, bug9605) {1.times(&->(n){ a += 1 })} assert_equal(3, a, bug9605) - assert_nothing_raised(ArgumentError, bug9605) {a = [[1, 2]].map(&->(x, y) {x+y})} - assert_equal([3], a, bug9605) + assert_nothing_raised(ArgumentError, bug9605) { + a = %w(Hi there how are you).each_with_index.detect(&->(w, i) {w.length == 3}) + } + assert_equal(["how", 2], a, bug9605) end def test_call_rest_args @@ -60,9 +63,9 @@ class TestLambdaParameters < Test::Unit::TestCase assert_equal(nil, ->(&b){ b }.call) foo { puts "bogus block " } assert_equal(1, ->(&b){ b.call }.call { 1 }) - b = nil - assert_equal(1, ->(&b){ b.call }.call { 1 }) - assert_nil(b) + _b = nil + assert_equal(1, ->(&_b){ _b.call }.call { 1 }) + assert_nil(_b) end def test_call_block_from_lambda @@ -71,6 +74,32 @@ class TestLambdaParameters < Test::Unit::TestCase assert_raise(ArgumentError, bug9605) {proc(&plus).call [1,2]} end + def pass_along(&block) + lambda(&block) + end + + def pass_along2(&block) + pass_along(&block) + end + + def test_create_non_lambda_for_proc_one_level + prev_warning, Warning[:deprecated] = Warning[:deprecated], false + f = pass_along {} + refute_predicate(f, :lambda?, '[Bug #15620]') + assert_nothing_raised(ArgumentError) { f.call(:extra_arg) } + ensure + Warning[:deprecated] = prev_warning + end + + def test_create_non_lambda_for_proc_two_levels + prev_warning, Warning[:deprecated] = Warning[:deprecated], false + f = pass_along2 {} + refute_predicate(f, :lambda?, '[Bug #15620]') + assert_nothing_raised(ArgumentError) { f.call(:extra_arg) } + ensure + Warning[:deprecated] = prev_warning + end + def test_instance_exec bug12568 = '[ruby-core:76300] [Bug #12568]' assert_nothing_raised(ArgumentError, bug12568) do @@ -78,29 +107,29 @@ class TestLambdaParameters < Test::Unit::TestCase end end - def yield_1(arg) - yield arg - end - - tap do |;bug9605, expected, result| - bug9605 = '[ruby-core:65887] [Bug #9605] arity check should be relaxed' - expected = [1,2,3] - - [ - ["array", expected], - ["to_ary", Struct.new(:to_ary).new(expected)], - ].product \ - [ - ["proc", proc {|a, b, c| [a, b, c]}], - ["lambda", lambda {|a, b, c| [a, b, c]}], - ] do - |(vtype, val), (btype, block)| - define_method("test_yeild_relaxed(#{vtype},&#{btype})") do - result = assert_nothing_raised(ArgumentError, bug9605) { - break yield_1(val, &block) - } - assert_equal(expected, result, bug9605) - end + def test_instance_eval_return + bug13090 = '[ruby-core:78917] [Bug #13090] cannot return in lambdas' + x = :ng + assert_nothing_raised(LocalJumpError) do + x = instance_eval(&->(_){return :ok}) + end + ensure + assert_equal(:ok, x, bug13090) + end + + def test_instance_exec_return + bug13090 = '[ruby-core:78917] [Bug #13090] cannot return in lambdas' + x = :ng + assert_nothing_raised(LocalJumpError) do + x = instance_exec(&->(){return :ok}) + end + ensure + assert_equal(:ok, x, bug13090) + end + + def test_arity_error + assert_raise(ArgumentError, '[Bug #12705]') do + [1, 2].tap(&lambda {|a, b|}) end end @@ -154,6 +183,21 @@ class TestLambdaParameters < Test::Unit::TestCase assert_equal(42, return_in_callee(42), feature8693) end + def break_in_current(val) + 1.tap(&->(*) {break 0}) + val + end + + def break_in_callee(val) + yield_block(&->(*) {break 0}) + val + end + + def test_break + assert_equal(42, break_in_current(42)) + assert_equal(42, break_in_callee(42)) + end + def test_do_lambda_source_location exp_lineno = __LINE__ + 3 lmd = ->(x, @@ -177,4 +221,31 @@ class TestLambdaParameters < Test::Unit::TestCase assert_match(/^#{ Regexp.quote(__FILE__) }$/, file) assert_equal(exp_lineno, lineno, "must be at the beginning of the block") end + + def test_not_orphan_return + assert_equal(42, Module.new { extend self + def m1(&b) b.call end; def m2(); m1(&-> { return 42 }) end }.m2) + assert_equal(42, Module.new { extend self + def m1(&b) b end; def m2(); m1(&-> { return 42 }).call end }.m2) + assert_equal(42, Module.new { extend self + def m1(&b) b end; def m2(); m1(&-> { return 42 }) end }.m2.call) + end + + def test_not_orphan_break + assert_equal(42, Module.new { extend self + def m1(&b) b.call end; def m2(); m1(&-> { break 42 }) end }.m2) + assert_equal(42, Module.new { extend self + def m1(&b) b end; def m2(); m1(&-> { break 42 }).call end }.m2) + assert_equal(42, Module.new { extend self + def m1(&b) b end; def m2(); m1(&-> { break 42 }) end }.m2.call) + end + + def test_not_orphan_next + assert_equal(42, Module.new { extend self + def m1(&b) b.call end; def m2(); m1(&-> { next 42 }) end }.m2) + assert_equal(42, Module.new { extend self + def m1(&b) b end; def m2(); m1(&-> { next 42 }).call end }.m2) + assert_equal(42, Module.new { extend self + def m1(&b) b end; def m2(); m1(&-> { next 42 }) end }.m2.call) + end end |
