ruby/test/ruby/test_call.rb
2023-06-17 12:29:28 +09:00

1098 lines
40 KiB
Ruby

# frozen_string_literal: false
require 'test/unit'
require '-test-/iter'
class TestCall < Test::Unit::TestCase
def aaa(a, b=100, *rest)
res = [a, b]
res += rest if rest
return res
end
def test_call
assert_raise(ArgumentError) {aaa()}
assert_raise(ArgumentError) {aaa}
assert_equal([1, 100], aaa(1))
assert_equal([1, 2], aaa(1, 2))
assert_equal([1, 2, 3, 4], aaa(1, 2, 3, 4))
assert_equal([1, 2, 3, 4], aaa(1, *[2, 3, 4]))
end
def test_callinfo
bug9622 = '[ruby-core:61422] [Bug #9622]'
o = Class.new do
def foo(*args)
bar(:foo, *args)
end
def bar(name)
name
end
end.new
e = assert_raise(ArgumentError) {o.foo(100)}
assert_nothing_raised(ArgumentError) {o.foo}
assert_raise_with_message(ArgumentError, e.message, bug9622) {o.foo(100)}
end
def test_safe_call
s = Struct.new(:x, :y, :z)
o = s.new("x")
assert_equal("X", o.x&.upcase)
assert_nil(o.y&.upcase)
assert_equal("x", o.x)
o&.x = 6
assert_equal(6, o.x)
o&.x *= 7
assert_equal(42, o.x)
o&.y = 5
assert_equal(5, o.y)
o&.z ||= 6
assert_equal(6, o.z)
o&.z &&= 7
assert_equal(7, o.z)
o = nil
assert_nil(o&.x)
assert_nothing_raised(NoMethodError) {o&.x = raise}
assert_nothing_raised(NoMethodError) {o&.x = raise; nil}
assert_nothing_raised(NoMethodError) {o&.x *= raise}
assert_nothing_raised(NoMethodError) {o&.x *= raise; nil}
assert_nothing_raised(NoMethodError) {o&.x ||= raise}
assert_nothing_raised(NoMethodError) {o&.x ||= raise; nil}
assert_nothing_raised(NoMethodError) {o&.x &&= raise}
assert_nothing_raised(NoMethodError) {o&.x &&= raise; nil}
end
def test_safe_call_evaluate_arguments_only_method_call_is_made
count = 0
proc = proc { count += 1; 1 }
s = Struct.new(:x, :y)
o = s.new(["a", "b", "c"])
o.y&.at(proc.call)
assert_equal(0, count)
o.x&.at(proc.call)
assert_equal(1, count)
end
def test_safe_call_block_command
assert_nil(("a".sub! "b" do end&.foo 1))
end
def test_safe_call_block_call
assert_nil(("a".sub! "b" do end&.foo))
end
def test_safe_call_block_call_brace
assert_nil(("a".sub! "b" do end&.foo {}))
assert_nil(("a".sub! "b" do end&.foo do end))
end
def test_safe_call_block_call_command
assert_nil(("a".sub! "b" do end&.foo 1 do end))
end
def test_invalid_safe_call
h = nil
assert_raise(NoMethodError) {
h[:foo] = nil
}
end
def test_call_bmethod_proc
pr = proc{|sym| sym}
define_singleton_method(:a, &pr)
ary = [10]
assert_equal(10, a(*ary))
end
def test_call_bmethod_proc_restarg
pr = proc{|*sym| sym}
define_singleton_method(:a, &pr)
ary = [10]
assert_equal([10], a(*ary))
assert_equal([10], a(10))
end
def test_call_splat_order
bug12860 = '[ruby-core:77701] [Bug# 12860]'
ary = [1, 2]
assert_equal([1, 2, 1], aaa(*ary, ary.shift), bug12860)
ary = [1, 2]
assert_equal([0, 1, 2, 1], aaa(0, *ary, ary.shift), bug12860)
end
def test_call_block_order
bug16504 = '[ruby-core:96769] [Bug# 16504]'
b = proc{}
ary = [1, 2, b]
assert_equal([1, 2, b], aaa(*ary, &ary.pop), bug16504)
ary = [1, 2, b]
assert_equal([0, 1, 2, b], aaa(0, *ary, &ary.pop), bug16504)
end
OVER_STACK_LEN = (ENV['RUBY_OVER_STACK_LEN'] || 150).to_i # Greater than VM_ARGC_STACK_MAX
OVER_STACK_ARGV = OVER_STACK_LEN.times.to_a.freeze
def test_call_cfunc_splat_large_array_bug_4040
a = OVER_STACK_ARGV
assert_equal(a, [].push(*a))
assert_equal(a, [].push(a[0], *a[1..]))
assert_equal(a, [].push(a[0], a[1], *a[2..]))
assert_equal(a, [].push(*a[0..1], *a[2..]))
assert_equal(a, [].push(*a[...-1], a[-1]))
assert_equal(a, [].push(a[0], *a[1...-1], a[-1]))
assert_equal(a, [].push(a[0], a[1], *a[2...-1], a[-1]))
assert_equal(a, [].push(*a[0..1], *a[2...-1], a[-1]))
assert_equal(a, [].push(*a[...-2], a[-2], a[-1]))
assert_equal(a, [].push(a[0], *a[1...-2], a[-2], a[-1]))
assert_equal(a, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1]))
assert_equal(a, [].push(*a[0..1], *a[2...-2], a[-2], a[-1]))
kw = {x: 1}
a_kw = a + [kw]
assert_equal(a_kw, [].push(*a, **kw))
assert_equal(a_kw, [].push(a[0], *a[1..], **kw))
assert_equal(a_kw, [].push(a[0], a[1], *a[2..], **kw))
assert_equal(a_kw, [].push(*a[0..1], *a[2..], **kw))
assert_equal(a_kw, [].push(*a[...-1], a[-1], **kw))
assert_equal(a_kw, [].push(a[0], *a[1...-1], a[-1], **kw))
assert_equal(a_kw, [].push(a[0], a[1], *a[2...-1], a[-1], **kw))
assert_equal(a_kw, [].push(*a[0..1], *a[2...-1], a[-1], **kw))
assert_equal(a_kw, [].push(*a[...-2], a[-2], a[-1], **kw))
assert_equal(a_kw, [].push(a[0], *a[1...-2], a[-2], a[-1], **kw))
assert_equal(a_kw, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1], **kw))
assert_equal(a_kw, [].push(*a[0..1], *a[2...-2], a[-2], a[-1], **kw))
assert_equal(a_kw, [].push(*a, x: 1))
assert_equal(a_kw, [].push(a[0], *a[1..], x: 1))
assert_equal(a_kw, [].push(a[0], a[1], *a[2..], x: 1))
assert_equal(a_kw, [].push(*a[0..1], *a[2..], x: 1))
assert_equal(a_kw, [].push(*a[...-1], a[-1], x: 1))
assert_equal(a_kw, [].push(a[0], *a[1...-1], a[-1], x: 1))
assert_equal(a_kw, [].push(a[0], a[1], *a[2...-1], a[-1], x: 1))
assert_equal(a_kw, [].push(*a[0..1], *a[2...-1], a[-1], x: 1))
assert_equal(a_kw, [].push(*a[...-2], a[-2], a[-1], x: 1))
assert_equal(a_kw, [].push(a[0], *a[1...-2], a[-2], a[-1], x: 1))
assert_equal(a_kw, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1], x: 1))
assert_equal(a_kw, [].push(*a[0..1], *a[2...-2], a[-2], a[-1], x: 1))
a_kw[-1][:y] = 2
kw = {y: 2}
assert_equal(a_kw, [].push(*a, x: 1, **kw))
assert_equal(a_kw, [].push(a[0], *a[1..], x: 1, **kw))
assert_equal(a_kw, [].push(a[0], a[1], *a[2..], x: 1, **kw))
assert_equal(a_kw, [].push(*a[0..1], *a[2..], x: 1, **kw))
assert_equal(a_kw, [].push(*a[...-1], a[-1], x: 1, **kw))
assert_equal(a_kw, [].push(a[0], *a[1...-1], a[-1], x: 1, **kw))
assert_equal(a_kw, [].push(a[0], a[1], *a[2...-1], a[-1], x: 1, **kw))
assert_equal(a_kw, [].push(*a[0..1], *a[2...-1], a[-1], x: 1, **kw))
assert_equal(a_kw, [].push(*a[...-2], a[-2], a[-1], x: 1, **kw))
assert_equal(a_kw, [].push(a[0], *a[1...-2], a[-2], a[-1], x: 1, **kw))
assert_equal(a_kw, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1], x: 1, **kw))
assert_equal(a_kw, [].push(*a[0..1], *a[2...-2], a[-2], a[-1], x: 1, **kw))
kw = {}
assert_equal(a, [].push(*a, **kw))
assert_equal(a, [].push(a[0], *a[1..], **kw))
assert_equal(a, [].push(a[0], a[1], *a[2..], **kw))
assert_equal(a, [].push(*a[0..1], *a[2..], **kw))
assert_equal(a, [].push(*a[...-1], a[-1], **kw))
assert_equal(a, [].push(a[0], *a[1...-1], a[-1], **kw))
assert_equal(a, [].push(a[0], a[1], *a[2...-1], a[-1], **kw))
assert_equal(a, [].push(*a[0..1], *a[2...-1], a[-1], **kw))
assert_equal(a, [].push(*a[...-2], a[-2], a[-1], **kw))
assert_equal(a, [].push(a[0], *a[1...-2], a[-2], a[-1], **kw))
assert_equal(a, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1], **kw))
assert_equal(a, [].push(*a[0..1], *a[2...-2], a[-2], a[-1], **kw))
a_kw = a + [Hash.ruby2_keywords_hash({})]
assert_equal(a, [].push(*a_kw))
# Single test with value that would cause SystemStackError.
# Not all tests use such a large array to reduce testing time.
assert_equal(1380888, [].push(*1380888.times.to_a).size)
end
def test_call_iseq_large_array_splat_fail
def self.a; end
def self.b(a=1); end
def self.c(k: 1); end
def self.d(**kw); end
def self.e(k: 1, **kw); end
def self.f(a=1, k: 1); end
def self.g(a=1, **kw); end
def self.h(a=1, k: 1, **kw); end
(:a..:h).each do |meth|
assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
instance_eval("#{meth}(*OVER_STACK_ARGV)", __FILE__, __LINE__)
end
end
end
def test_call_iseq_large_array_splat_pass
def self.a(*a); a.length end
assert_equal OVER_STACK_LEN, a(*OVER_STACK_ARGV)
def self.b(_, *a); a.length end
assert_equal (OVER_STACK_LEN - 1), b(*OVER_STACK_ARGV)
def self.c(_, *a, _); a.length end
assert_equal (OVER_STACK_LEN - 2), c(*OVER_STACK_ARGV)
def self.d(b=1, *a); a.length end
assert_equal (OVER_STACK_LEN - 1), d(*OVER_STACK_ARGV)
def self.e(b=1, *a, _); a.length end
assert_equal (OVER_STACK_LEN - 2), e(*OVER_STACK_ARGV)
def self.f(b, *a); a.length end
assert_equal (OVER_STACK_LEN - 1), f(*OVER_STACK_ARGV)
def self.g(*a, k: 1); a.length end
assert_equal OVER_STACK_LEN, g(*OVER_STACK_ARGV)
def self.h(*a, **kw); a.length end
assert_equal OVER_STACK_LEN, h(*OVER_STACK_ARGV)
def self.i(*a, k: 1, **kw); a.length end
assert_equal OVER_STACK_LEN, i(*OVER_STACK_ARGV)
def self.j(b=1, *a, k: 1); a.length end
assert_equal (OVER_STACK_LEN - 1), j(*OVER_STACK_ARGV)
def self.k(b=1, *a, **kw); a.length end
assert_equal (OVER_STACK_LEN - 1), k(*OVER_STACK_ARGV)
def self.l(b=1, *a, k: 1, **kw); a.length end
assert_equal (OVER_STACK_LEN - 1), l(*OVER_STACK_ARGV)
def self.m(b=1, *a, _, k: 1); a.length end
assert_equal (OVER_STACK_LEN - 2), m(*OVER_STACK_ARGV)
def self.n(b=1, *a, _, **kw); a.length end
assert_equal (OVER_STACK_LEN - 2), n(*OVER_STACK_ARGV)
def self.o(b=1, *a, _, k: 1, **kw); a.length end
assert_equal (OVER_STACK_LEN - 2), o(*OVER_STACK_ARGV)
end
def test_call_iseq_large_array_splat_with_large_number_of_parameters
args = OVER_STACK_ARGV.map{|i| "a#{i}"}.join(',')
args1 = (OVER_STACK_LEN-1).times.map{|i| "a#{i}"}.join(',')
singleton_class.class_eval("def a(#{args}); [#{args}] end")
assert_equal OVER_STACK_ARGV, a(*OVER_STACK_ARGV)
singleton_class.class_eval("def b(#{args}, b=0); [#{args}, b] end")
assert_equal(OVER_STACK_ARGV + [0], b(*OVER_STACK_ARGV))
singleton_class.class_eval("def c(#{args}, *b); [#{args}, b] end")
assert_equal(OVER_STACK_ARGV + [[]], c(*OVER_STACK_ARGV))
singleton_class.class_eval("def d(#{args1}, *b); [#{args1}, b] end")
assert_equal(OVER_STACK_ARGV[0...-1] + [[OVER_STACK_ARGV.last]], d(*OVER_STACK_ARGV))
end if OVER_STACK_LEN < 200
def test_call_proc_large_array_splat_pass
[
proc{0} ,
proc{|a=1|a},
proc{|k: 1|0},
proc{|**kw| 0},
proc{|k: 1, **kw| 0},
proc{|a=1, k: 1| a},
proc{|a=1, **kw| a},
proc{|a=1, k: 1, **kw| a},
].each do |l|
assert_equal 0, l.call(*OVER_STACK_ARGV)
end
assert_equal OVER_STACK_LEN, proc{|*a| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), proc{|_, *a| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), proc{|_, *a, _| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), proc{|b=1, *a, _| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a| a.length}.(*OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, proc{|*a, k: 1| a.length}.(*OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, proc{|*a, **kw| a.length}.(*OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, proc{|*a, k: 1, **kw| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a, k: 1| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a, **kw| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a, k: 1, **kw| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), proc{|b=1, *a, _, k: 1| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), proc{|b=1, *a, _, **kw| a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), proc{|b=1, *a, _, k: 1, **kw| a.length}.(*OVER_STACK_ARGV)
end
def test_call_proc_large_array_splat_with_large_number_of_parameters
args = OVER_STACK_ARGV.map{|i| "a#{i}"}.join(',')
args1 = (OVER_STACK_LEN-1).times.map{|i| "a#{i}"}.join(',')
l = instance_eval("proc{|#{args}| [#{args}]}")
assert_equal OVER_STACK_ARGV, l.(*OVER_STACK_ARGV)
l = instance_eval("proc{|#{args}, b| [#{args}, b]}")
assert_equal(OVER_STACK_ARGV + [nil], l.(*OVER_STACK_ARGV))
l = instance_eval("proc{|#{args1}| [#{args1}]}")
assert_equal(OVER_STACK_ARGV[0...-1], l.(*OVER_STACK_ARGV))
l = instance_eval("proc{|#{args}, *b| [#{args}, b]}")
assert_equal(OVER_STACK_ARGV + [[]], l.(*OVER_STACK_ARGV))
l = instance_eval("proc{|#{args1}, *b| [#{args1}, b]}")
assert_equal(OVER_STACK_ARGV[0...-1] + [[OVER_STACK_ARGV.last]], l.(*OVER_STACK_ARGV))
l = instance_eval("proc{|#{args}, b, *c| [#{args}, b, c]}")
assert_equal(OVER_STACK_ARGV + [nil, []], l.(*OVER_STACK_ARGV))
l = instance_eval("proc{|#{args}, b, *c, d| [#{args}, b, c, d]}")
assert_equal(OVER_STACK_ARGV + [nil, [], nil], l.(*OVER_STACK_ARGV))
end if OVER_STACK_LEN < 200
def test_call_lambda_large_array_splat_fail
[
->{} ,
->(a=1){},
->(k: 1){},
->(**kw){},
->(k: 1, **kw){},
->(a=1, k: 1){},
->(a=1, **kw){},
->(a=1, k: 1, **kw){},
].each do |l|
assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
l.call(*OVER_STACK_ARGV)
end
end
end
def test_call_lambda_large_array_splat_pass
assert_equal OVER_STACK_LEN, ->(*a){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), ->(_, *a){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), ->(_, *a, _){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), ->(b=1, *a){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), ->(b=1, *a, _){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), ->(b, *a){a.length}.(*OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, ->(*a, k: 1){a.length}.(*OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, ->(*a, **kw){a.length}.(*OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, ->(*a, k: 1, **kw){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), ->(b=1, *a, k: 1){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), ->(b=1, *a, **kw){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 1), ->(b=1, *a, k: 1, **kw){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), ->(b=1, *a, _, k: 1){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), ->(b=1, *a, _, **kw){a.length}.(*OVER_STACK_ARGV)
assert_equal (OVER_STACK_LEN - 2), ->(b=1, *a, _, k: 1, **kw){a.length}.(*OVER_STACK_ARGV)
end
def test_call_yield_block_large_array_splat_pass
def self.a
yield(*OVER_STACK_ARGV)
end
[
proc{0} ,
proc{|a=1|a},
proc{|k: 1|0},
proc{|**kw| 0},
proc{|k: 1, **kw| 0},
proc{|a=1, k: 1| a},
proc{|a=1, **kw| a},
proc{|a=1, k: 1, **kw| a},
].each do |l|
assert_equal 0, a(&l)
end
assert_equal OVER_STACK_LEN, a{|*a| a.length}
assert_equal (OVER_STACK_LEN - 1), a{|_, *a| a.length}
assert_equal (OVER_STACK_LEN - 2), a{|_, *a, _| a.length}
assert_equal (OVER_STACK_LEN - 1), a{|b=1, *a| a.length}
assert_equal (OVER_STACK_LEN - 2), a{|b=1, *a, _| a.length}
assert_equal (OVER_STACK_LEN - 1), a{|b, *a| a.length}
assert_equal OVER_STACK_LEN, a{|*a, k: 1| a.length}
assert_equal OVER_STACK_LEN, a{|*a, **kw| a.length}
assert_equal OVER_STACK_LEN, a{|*a, k: 1, **kw| a.length}
assert_equal (OVER_STACK_LEN - 1), a{|b=1, *a, k: 1| a.length}
assert_equal (OVER_STACK_LEN - 1), a{|b=1, *a, **kw| a.length}
assert_equal (OVER_STACK_LEN - 1), a{|b=1, *a, k: 1, **kw| a.length}
assert_equal (OVER_STACK_LEN - 2), a{|b=1, *a, _, k: 1| a.length}
assert_equal (OVER_STACK_LEN - 2), a{|b=1, *a, _, **kw| a.length}
assert_equal (OVER_STACK_LEN - 2), a{|b=1, *a, _, k: 1, **kw| a.length}
end
def test_call_yield_large_array_splat_with_large_number_of_parameters
def self.a
yield(*OVER_STACK_ARGV)
end
args = OVER_STACK_ARGV.map{|i| "a#{i}"}.join(',')
args1 = (OVER_STACK_LEN-1).times.map{|i| "a#{i}"}.join(',')
assert_equal OVER_STACK_ARGV, instance_eval("a{|#{args}| [#{args}]}", __FILE__, __LINE__)
assert_equal(OVER_STACK_ARGV + [nil], instance_eval("a{|#{args}, b| [#{args}, b]}", __FILE__, __LINE__))
assert_equal(OVER_STACK_ARGV[0...-1], instance_eval("a{|#{args1}| [#{args1}]}", __FILE__, __LINE__))
assert_equal(OVER_STACK_ARGV + [[]], instance_eval("a{|#{args}, *b| [#{args}, b]}", __FILE__, __LINE__))
assert_equal(OVER_STACK_ARGV[0...-1] + [[OVER_STACK_ARGV.last]], instance_eval("a{|#{args1}, *b| [#{args1}, b]}", __FILE__, __LINE__))
assert_equal(OVER_STACK_ARGV + [nil, []], instance_eval("a{|#{args}, b, *c| [#{args}, b, c]}", __FILE__, __LINE__))
assert_equal(OVER_STACK_ARGV + [nil, [], nil], instance_eval("a{|#{args}, b, *c, d| [#{args}, b, c, d]}", __FILE__, __LINE__))
end if OVER_STACK_LEN < 200
def test_call_yield_lambda_large_array_splat_fail
def self.a
yield(*OVER_STACK_ARGV)
end
[
->{} ,
->(a=1){},
->(k: 1){},
->(**kw){},
->(k: 1, **kw){},
->(a=1, k: 1){},
->(a=1, **kw){},
->(a=1, k: 1, **kw){},
].each do |l|
assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
a(&l)
end
end
end
def test_call_yield_lambda_large_array_splat_pass
def self.a
yield(*OVER_STACK_ARGV)
end
assert_equal OVER_STACK_LEN, a(&->(*a){a.length})
assert_equal (OVER_STACK_LEN - 1), a(&->(_, *a){a.length})
assert_equal (OVER_STACK_LEN - 2), a(&->(_, *a, _){a.length})
assert_equal (OVER_STACK_LEN - 1), a(&->(b=1, *a){a.length})
assert_equal (OVER_STACK_LEN - 2), a(&->(b=1, *a, _){a.length})
assert_equal (OVER_STACK_LEN - 1), a(&->(b, *a){a.length})
assert_equal OVER_STACK_LEN, a(&->(*a, k: 1){a.length})
assert_equal OVER_STACK_LEN, a(&->(*a, **kw){a.length})
assert_equal OVER_STACK_LEN, a(&->(*a, k: 1, **kw){a.length})
assert_equal (OVER_STACK_LEN - 1), a(&->(b=1, *a, k: 1){a.length})
assert_equal (OVER_STACK_LEN - 1), a(&->(b=1, *a, **kw){a.length})
assert_equal (OVER_STACK_LEN - 1), a(&->(b=1, *a, k: 1, **kw){a.length})
assert_equal (OVER_STACK_LEN - 2), a(&->(b=1, *a, _, k: 1){a.length})
assert_equal (OVER_STACK_LEN - 2), a(&->(b=1, *a, _, **kw){a.length})
assert_equal (OVER_STACK_LEN - 2), a(&->(b=1, *a, _, k: 1, **kw){a.length})
end
def test_call_send_iseq_large_array_splat_fail
def self.a; end
def self.b(a=1); end
def self.c(k: 1); end
def self.d(**kw); end
def self.e(k: 1, **kw); end
def self.f(a=1, k: 1); end
def self.g(a=1, **kw); end
def self.h(a=1, k: 1, **kw); end
(:a..:h).each do |meth|
assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
send(meth, *OVER_STACK_ARGV)
end
end
end
def test_call_send_iseq_large_array_splat_pass
def self.a(*a); a.length end
assert_equal OVER_STACK_LEN, send(:a, *OVER_STACK_ARGV)
def self.b(_, *a); a.length end
assert_equal (OVER_STACK_LEN - 1), send(:b, *OVER_STACK_ARGV)
def self.c(_, *a, _); a.length end
assert_equal (OVER_STACK_LEN - 2), send(:c, *OVER_STACK_ARGV)
def self.d(b=1, *a); a.length end
assert_equal (OVER_STACK_LEN - 1), send(:d, *OVER_STACK_ARGV)
def self.e(b=1, *a, _); a.length end
assert_equal (OVER_STACK_LEN - 2), send(:e, *OVER_STACK_ARGV)
def self.f(b, *a); a.length end
assert_equal (OVER_STACK_LEN - 1), send(:f, *OVER_STACK_ARGV)
def self.g(*a, k: 1); a.length end
assert_equal OVER_STACK_LEN, send(:g, *OVER_STACK_ARGV)
def self.h(*a, **kw); a.length end
assert_equal OVER_STACK_LEN, send(:h, *OVER_STACK_ARGV)
def self.i(*a, k: 1, **kw); a.length end
assert_equal OVER_STACK_LEN, send(:i, *OVER_STACK_ARGV)
def self.j(b=1, *a, k: 1); a.length end
assert_equal (OVER_STACK_LEN - 1), send(:j, *OVER_STACK_ARGV)
def self.k(b=1, *a, **kw); a.length end
assert_equal (OVER_STACK_LEN - 1), send(:k, *OVER_STACK_ARGV)
def self.l(b=1, *a, k: 1, **kw); a.length end
assert_equal (OVER_STACK_LEN - 1), send(:l, *OVER_STACK_ARGV)
def self.m(b=1, *a, _, k: 1); a.length end
assert_equal (OVER_STACK_LEN - 2), send(:m, *OVER_STACK_ARGV)
def self.n(b=1, *a, _, **kw); a.length end
assert_equal (OVER_STACK_LEN - 2), send(:n, *OVER_STACK_ARGV)
def self.o(b=1, *a, _, k: 1, **kw); a.length end
assert_equal (OVER_STACK_LEN - 2), send(:o, *OVER_STACK_ARGV)
end
def test_call_send_iseq_large_array_splat_with_large_number_of_parameters
args = OVER_STACK_ARGV.map{|i| "a#{i}"}.join(',')
args1 = (OVER_STACK_LEN-1).times.map{|i| "a#{i}"}.join(',')
singleton_class.class_eval("def a(#{args}); [#{args}] end")
assert_equal OVER_STACK_ARGV, send(:a, *OVER_STACK_ARGV)
singleton_class.class_eval("def b(#{args}, b=0); [#{args}, b] end")
assert_equal(OVER_STACK_ARGV + [0], send(:b, *OVER_STACK_ARGV))
singleton_class.class_eval("def c(#{args}, *b); [#{args}, b] end")
assert_equal(OVER_STACK_ARGV + [[]], send(:c, *OVER_STACK_ARGV))
singleton_class.class_eval("def d(#{args1}, *b); [#{args1}, b] end")
assert_equal(OVER_STACK_ARGV[0...-1] + [[OVER_STACK_ARGV.last]], send(:d, *OVER_STACK_ARGV))
end if OVER_STACK_LEN < 200
def test_call_send_cfunc_large_array_splat_fail
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
send(:object_id, *OVER_STACK_ARGV)
end
end
def test_call_send_cfunc_large_array_splat_pass
assert_equal OVER_STACK_LEN, [].send(:push, *OVER_STACK_ARGV).length
end
def test_call_attr_reader_large_array_splat_fail
singleton_class.send(:attr_reader, :a)
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
a(*OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
send(:a, *OVER_STACK_ARGV)
end
end
def test_call_attr_writer_large_array_splat_fail
singleton_class.send(:attr_writer, :a)
singleton_class.send(:alias_method, :a, :a=)
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
a(*OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
send(:a, *OVER_STACK_ARGV)
end
end
def test_call_struct_aref_large_array_splat_fail
s = Struct.new(:a).new
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
s.a(*OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
s.send(:a, *OVER_STACK_ARGV)
end
end
def test_call_struct_aset_large_array_splat_fail
s = Struct.new(:a) do
alias b a=
end.new
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
s.b(*OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
s.send(:b, *OVER_STACK_ARGV)
end
end
def test_call_alias_large_array_splat
c = Class.new do
def a; end
def c(*a); a.length end
attr_accessor :e
end
sc = Class.new(c) do
alias b a
alias d c
alias f e
alias g e=
end
obj = sc.new
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
obj.b(*OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
obj.f(*OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
obj.g(*OVER_STACK_ARGV)
end
assert_equal OVER_STACK_LEN, obj.d(*OVER_STACK_ARGV)
end
def test_call_zsuper_large_array_splat
c = Class.new do
private
def a; end
def c(*a); a.length end
attr_reader :e
end
sc = Class.new(c) do
public :a
public :c
public :e
end
obj = sc.new
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
obj.a(*OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
obj.e(*OVER_STACK_ARGV)
end
assert_equal OVER_STACK_LEN, obj.c(*OVER_STACK_ARGV)
end
class RefinedModuleLargeArrayTest
c = self
using(Module.new do
refine c do
def a; end
def c(*a) a.length end
attr_reader :e
end
end)
def b
a(*OVER_STACK_ARGV)
end
def d
c(*OVER_STACK_ARGV)
end
def f
e(*OVER_STACK_ARGV)
end
end
def test_call_refined_large_array_splat_fail
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
RefinedModuleLargeArrayTest.new.b
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
RefinedModuleLargeArrayTest.new.f
end
end
def test_call_refined_large_array_splat_pass
assert_equal OVER_STACK_LEN, RefinedModuleLargeArrayTest.new.d
end
def test_call_method_missing_iseq_large_array_splat_fail
def self.method_missing(_) end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
nonexistent_method(*OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
send(:nonexistent_method, *OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
send("nonexistent_method123", *OVER_STACK_ARGV)
end
end
def test_call_method_missing_iseq_large_array_splat_pass
def self.method_missing(m, *a)
a.length
end
assert_equal OVER_STACK_LEN, nonexistent_method(*OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, send(:nonexistent_method, *OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, send("nonexistent_method123", *OVER_STACK_ARGV)
end
def test_call_bmethod_large_array_splat_fail
define_singleton_method(:a){}
define_singleton_method(:b){|a=1|}
define_singleton_method(:c){|k: 1|}
define_singleton_method(:d){|**kw|}
define_singleton_method(:e){|k: 1, **kw|}
define_singleton_method(:f){|a=1, k: 1|}
define_singleton_method(:g){|a=1, **kw|}
define_singleton_method(:h){|a=1, k: 1, **kw|}
(:a..:h).each do |meth|
assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
instance_eval("#{meth}(*OVER_STACK_ARGV)", __FILE__, __LINE__)
end
end
end
def test_call_bmethod_large_array_splat_pass
define_singleton_method(:a){|*a| a.length}
assert_equal OVER_STACK_LEN, a(*OVER_STACK_ARGV)
define_singleton_method(:b){|_, *a| a.length}
assert_equal (OVER_STACK_LEN - 1), b(*OVER_STACK_ARGV)
define_singleton_method(:c){|_, *a, _| a.length}
assert_equal (OVER_STACK_LEN - 2), c(*OVER_STACK_ARGV)
define_singleton_method(:d){|b=1, *a| a.length}
assert_equal (OVER_STACK_LEN - 1), d(*OVER_STACK_ARGV)
define_singleton_method(:e){|b=1, *a, _| a.length}
assert_equal (OVER_STACK_LEN - 2), e(*OVER_STACK_ARGV)
define_singleton_method(:f){|b, *a| a.length}
assert_equal (OVER_STACK_LEN - 1), f(*OVER_STACK_ARGV)
define_singleton_method(:g){|*a, k: 1| a.length}
assert_equal OVER_STACK_LEN, g(*OVER_STACK_ARGV)
define_singleton_method(:h){|*a, **kw| a.length}
assert_equal OVER_STACK_LEN, h(*OVER_STACK_ARGV)
define_singleton_method(:i){|*a, k: 1, **kw| a.length}
assert_equal OVER_STACK_LEN, i(*OVER_STACK_ARGV)
define_singleton_method(:j){|b=1, *a, k: 1| a.length}
assert_equal (OVER_STACK_LEN - 1), j(*OVER_STACK_ARGV)
define_singleton_method(:k){|b=1, *a, **kw| a.length}
assert_equal (OVER_STACK_LEN - 1), k(*OVER_STACK_ARGV)
define_singleton_method(:l){|b=1, *a, k: 1, **kw| a.length}
assert_equal (OVER_STACK_LEN - 1), l(*OVER_STACK_ARGV)
define_singleton_method(:m){|b=1, *a, _, k: 1| a.length}
assert_equal (OVER_STACK_LEN - 2), m(*OVER_STACK_ARGV)
define_singleton_method(:n){|b=1, *a, _, **kw| a.length}
assert_equal (OVER_STACK_LEN - 2), n(*OVER_STACK_ARGV)
define_singleton_method(:o){|b=1, *a, _, k: 1, **kw| a.length}
assert_equal (OVER_STACK_LEN - 2), o(*OVER_STACK_ARGV)
end
def test_call_method_missing_bmethod_large_array_splat_fail
define_singleton_method(:method_missing){|_|}
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
nonexistent_method(*OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
send(:nonexistent_method, *OVER_STACK_ARGV)
end
assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
send("nonexistent_method123", *OVER_STACK_ARGV)
end
end
def test_call_method_missing_bmethod_large_array_splat_pass
define_singleton_method(:method_missing){|_, *a| a.length}
assert_equal OVER_STACK_LEN, nonexistent_method(*OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, send(:nonexistent_method, *OVER_STACK_ARGV)
assert_equal OVER_STACK_LEN, send("nonexistent_method123", *OVER_STACK_ARGV)
end
def test_call_symproc_large_array_splat_fail
define_singleton_method(:a){}
define_singleton_method(:b){|a=1|}
define_singleton_method(:c){|k: 1|}
define_singleton_method(:d){|**kw|}
define_singleton_method(:e){|k: 1, **kw|}
define_singleton_method(:f){|a=1, k: 1|}
define_singleton_method(:g){|a=1, **kw|}
define_singleton_method(:h){|a=1, k: 1, **kw|}
(:a..:h).each do |meth|
assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
instance_eval(":#{meth}.to_proc.(self, *OVER_STACK_ARGV)", __FILE__, __LINE__)
end
end
end
def test_call_symproc_large_array_splat_pass
define_singleton_method(:a){|*a| a.length}
assert_equal OVER_STACK_LEN, :a.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:b){|_, *a| a.length}
assert_equal (OVER_STACK_LEN - 1), :b.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:c){|_, *a, _| a.length}
assert_equal (OVER_STACK_LEN - 2), :c.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:d){|b=1, *a| a.length}
assert_equal (OVER_STACK_LEN - 1), :d.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:e){|b=1, *a, _| a.length}
assert_equal (OVER_STACK_LEN - 2), :e.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:f){|b, *a| a.length}
assert_equal (OVER_STACK_LEN - 1), :f.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:g){|*a, k: 1| a.length}
assert_equal OVER_STACK_LEN, :g.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:h){|*a, **kw| a.length}
assert_equal OVER_STACK_LEN, :h.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:i){|*a, k: 1, **kw| a.length}
assert_equal OVER_STACK_LEN, :i.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:j){|b=1, *a, k: 1| a.length}
assert_equal (OVER_STACK_LEN - 1), :j.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:k){|b=1, *a, **kw| a.length}
assert_equal (OVER_STACK_LEN - 1), :k.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:l){|b=1, *a, k: 1, **kw| a.length}
assert_equal (OVER_STACK_LEN - 1), :l.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:m){|b=1, *a, _, k: 1| a.length}
assert_equal (OVER_STACK_LEN - 2), :m.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:n){|b=1, *a, _, **kw| a.length}
assert_equal (OVER_STACK_LEN - 2), :n.to_proc.(self, *OVER_STACK_ARGV)
define_singleton_method(:o){|b=1, *a, _, k: 1, **kw| a.length}
assert_equal (OVER_STACK_LEN - 2), :o.to_proc.(self, *OVER_STACK_ARGV)
end
def test_call_rb_call_iseq_large_array_splat_fail
extend Bug::Iter::Yield
l = ->(*a){}
def self.a; end
def self.b(a=1) end
def self.c(k: 1) end
def self.d(**kw) end
def self.e(k: 1, **kw) end
def self.f(a=1, k: 1) end
def self.g(a=1, **kw) end
def self.h(a=1, k: 1, **kw) end
(:a..:h).each do |meth|
assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
yield_block(meth, *OVER_STACK_ARGV, &l)
end
end
end
def test_call_rb_call_iseq_large_array_splat_pass
extend Bug::Iter::Yield
l = ->(*a){a.length}
def self.a(*a) a.length end
assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
def self.b(_, *a) a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:b, *OVER_STACK_ARGV, &l)
def self.c(_, *a, _) a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:c, *OVER_STACK_ARGV, &l)
def self.d(b=1, *a) a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:d, *OVER_STACK_ARGV, &l)
def self.e(b=1, *a, _) a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:e, *OVER_STACK_ARGV, &l)
def self.f(b, *a) a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:f, *OVER_STACK_ARGV, &l)
def self.g(*a, k: 1) a.length end
assert_equal OVER_STACK_LEN, yield_block(:g, *OVER_STACK_ARGV, &l)
def self.h(*a, **kw) a.length end
assert_equal OVER_STACK_LEN, yield_block(:h, *OVER_STACK_ARGV, &l)
def self.i(*a, k: 1, **kw) a.length end
assert_equal OVER_STACK_LEN, yield_block(:h, *OVER_STACK_ARGV, &l)
def self.j(b=1, *a, k: 1) a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:j, *OVER_STACK_ARGV, &l)
def self.k(b=1, *a, **kw) a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:k, *OVER_STACK_ARGV, &l)
def self.l(b=1, *a, k: 1, **kw) a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:l, *OVER_STACK_ARGV, &l)
def self.m(b=1, *a, _, k: 1) a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:m, *OVER_STACK_ARGV, &l)
def self.n(b=1, *a, _, **kw) a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:n, *OVER_STACK_ARGV, &l)
def self.o(b=1, *a, _, k: 1, **kw) a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:o, *OVER_STACK_ARGV, &l)
end
def test_call_rb_call_bmethod_large_array_splat_fail
extend Bug::Iter::Yield
l = ->(*a){}
define_singleton_method(:a){||}
define_singleton_method(:b){|a=1|}
define_singleton_method(:c){|k: 1|}
define_singleton_method(:d){|**kw|}
define_singleton_method(:e){|k: 1, **kw|}
define_singleton_method(:f){|a=1, k: 1|}
define_singleton_method(:g){|a=1, **kw|}
define_singleton_method(:h){|a=1, k: 1, **kw|}
(:a..:h).each do |meth|
assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
yield_block(meth, *OVER_STACK_ARGV, &l)
end
end
end
def test_call_rb_call_bmethod_large_array_splat_pass
extend Bug::Iter::Yield
l = ->(*a){a.length}
define_singleton_method(:a){|*a| a.length}
assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
define_singleton_method(:b){|_, *a| a.length}
assert_equal (OVER_STACK_LEN - 1), yield_block(:b, *OVER_STACK_ARGV, &l)
define_singleton_method(:c){|_, *a, _| a.length}
assert_equal (OVER_STACK_LEN - 2), yield_block(:c, *OVER_STACK_ARGV, &l)
define_singleton_method(:d){|b=1, *a| a.length}
assert_equal (OVER_STACK_LEN - 1), yield_block(:d, *OVER_STACK_ARGV, &l)
define_singleton_method(:e){|b=1, *a, _| a.length}
assert_equal (OVER_STACK_LEN - 2), yield_block(:e, *OVER_STACK_ARGV, &l)
define_singleton_method(:f){|b, *a| a.length}
assert_equal (OVER_STACK_LEN - 1), yield_block(:f, *OVER_STACK_ARGV, &l)
define_singleton_method(:g){|*a, k: 1| a.length}
assert_equal OVER_STACK_LEN, yield_block(:g, *OVER_STACK_ARGV, &l)
define_singleton_method(:h){|*a, **kw| a.length}
assert_equal OVER_STACK_LEN, yield_block(:h, *OVER_STACK_ARGV, &l)
define_singleton_method(:i){|*a, k: 1, **kw| a.length}
assert_equal OVER_STACK_LEN, yield_block(:h, *OVER_STACK_ARGV, &l)
define_singleton_method(:j){|b=1, *a, k: 1| a.length}
assert_equal (OVER_STACK_LEN - 1), yield_block(:j, *OVER_STACK_ARGV, &l)
define_singleton_method(:k){|b=1, *a, **kw| a.length}
assert_equal (OVER_STACK_LEN - 1), yield_block(:k, *OVER_STACK_ARGV, &l)
define_singleton_method(:l){|b=1, *a, k: 1, **kw| a.length}
assert_equal (OVER_STACK_LEN - 1), yield_block(:l, *OVER_STACK_ARGV, &l)
define_singleton_method(:m){|b=1, *a, _, k: 1| a.length}
assert_equal (OVER_STACK_LEN - 2), yield_block(:m, *OVER_STACK_ARGV, &l)
define_singleton_method(:n){|b=1, *a, _, **kw| a.length}
assert_equal (OVER_STACK_LEN - 2), yield_block(:n, *OVER_STACK_ARGV, &l)
define_singleton_method(:o){|b=1, *a, _, k: 1, **kw| a.length}
assert_equal (OVER_STACK_LEN - 2), yield_block(:o, *OVER_STACK_ARGV, &l)
end
def test_call_ifunc_iseq_large_array_splat_fail
extend Bug::Iter::Yield
def self.a(*a)
yield(*a)
end
[
->(){},
->(a=1){},
->(k: 1){},
->(**kw){},
->(k: 1, **kw){},
->(a=1, k: 1){},
->(a=1, **kw){},
->(a=1, k: 1, **kw){},
].each do |l|
assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
yield_block(:a, *OVER_STACK_ARGV, &l)
end
end
end
def test_call_ifunc_iseq_large_array_splat_pass
extend Bug::Iter::Yield
def self.a(*a)
yield(*a)
end
l = ->(*a) do a.length end
assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(_, *a) do a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(_, *a, _) do a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(b=1, *a) do a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(b=1, *a, _) do a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(b, *a) do a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(*a, k: 1) do a.length end
assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(*a, **kw) do a.length end
assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(*a, k: 1, **kw) do a.length end
assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(b=1, *a, k: 1) do a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(b=1, *a, **kw) do a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(b=1, *a, k: 1, **kw) do a.length end
assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(b=1, *a, _, k: 1) do a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(b=1, *a, _, **kw) do a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
l = ->(b=1, *a, _, k: 1, **kw) do a.length end
assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
end
end