diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/ruby/test_allocation.rb | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/test/ruby/test_allocation.rb b/test/ruby/test_allocation.rb index 60faa44e4f..9ba01dfcf9 100644 --- a/test/ruby/test_allocation.rb +++ b/test/ruby/test_allocation.rb @@ -2,10 +2,16 @@ require 'test/unit' class TestAllocation < Test::Unit::TestCase + def munge_checks(checks) + checks + end + def check_allocations(checks) dups = checks.split("\n").reject(&:empty?).tally.select{|_,v| v > 1} raise "duplicate checks:\n#{dups.keys.join("\n")}" unless dups.empty? + checks = munge_checks(checks) + assert_separately([], <<~RUBY) $allocations = [0, 0] $counts = {} @@ -549,7 +555,8 @@ class TestAllocation < Test::Unit::TestCase def test_nested_anonymous_splat_and_anonymous_keyword_splat_parameters check_allocations(<<~RUBY) - def self.anon_splat_and_anon_keyword_splat(*, **#{block}); t(*, **) end; def self.t(*, **#{block}); end + def self.t(*, **#{block}); end + def self.anon_splat_and_anon_keyword_splat(*, **#{block}); t(*, **) end check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, a: 2#{block})") check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, *empty_array, a: 2#{block})") @@ -639,7 +646,8 @@ class TestAllocation < Test::Unit::TestCase def test_nested_argument_forwarding check_allocations(<<~RUBY) - def self.argument_forwarding(...); t(...) end; def self.t(...) end + def self.t(...) end + def self.argument_forwarding(...); t(...) end check_allocations(0, 0, "argument_forwarding(1, a: 2#{block})") check_allocations(0, 0, "argument_forwarding(1, *empty_array, a: 2#{block})") @@ -766,4 +774,69 @@ class TestAllocation < Test::Unit::TestCase end end end + + class ProcCall < MethodCall + def munge_checks(checks) + return checks if @no_munge + sub = rep = nil + checks.split("\n").map do |line| + case line + when "singleton_class.send(:ruby2_keywords, :r2k)" + "r2k.ruby2_keywords" + when /\Adef self.([a-z0-9_]+)\((.*)\);(.*)end\z/ + sub = $1 + '(' + rep = $1 + '.(' + "#{$1} = #{$1} = proc{ |#{$2}| #{$3} }" + when /check_allocations/ + line.gsub(sub, rep) + else + line + end + end.join("\n") + end + + # Generic argument forwarding not supported in proc definitions + undef_method :test_argument_forwarding + undef_method :test_nested_argument_forwarding + + # Proc anonymous arguments cannot be used directly + undef_method :test_nested_anonymous_splat_and_anonymous_keyword_splat_parameters + + def test_no_array_allocation_with_splat_and_nonstatic_keywords + @no_munge = true + + check_allocations(<<~RUBY) + keyword = keyword = proc{ |a: nil, b: nil #{block}| } + + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array#{block})") # LVAR + check_allocations(0, 1, "->{keyword.(*empty_array, a: empty_array#{block})}.call") # DVAR + check_allocations(0, 1, "$x = empty_array; keyword.(*empty_array, a: $x#{block})") # GVAR + check_allocations(0, 1, "@x = empty_array; keyword.(*empty_array, a: @x#{block})") # IVAR + check_allocations(0, 1, "self.class.const_set(:X, empty_array); keyword.(*empty_array, a: X#{block})") # CONST + check_allocations(0, 1, "keyword.(*empty_array, a: Object::X#{block})") # COLON2 + check_allocations(0, 1, "keyword.(*empty_array, a: ::X#{block})") # COLON3 + check_allocations(0, 1, "T = keyword; #{'B = block' unless block.empty?}; class Object; @@x = X; T.(*X, a: @@x#{', &B' unless block.empty?}) end") # CVAR + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: 1#{block})") # INTEGER + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: 1.0#{block})") # FLOAT + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: 1.0r#{block})") # RATIONAL + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: 1.0i#{block})") # IMAGINARY + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: 'a'#{block})") # STR + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: :b#{block})") # SYM + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: /a/#{block})") # REGX + check_allocations(0, 1, "keyword.(*empty_array, a: self#{block})") # SELF + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: nil#{block})") # NIL + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: true#{block})") # TRUE + check_allocations(0, 1, "keyword.(*empty_array, a: empty_array, b: false#{block})") # FALSE + check_allocations(0, 1, "keyword.(*empty_array, a: ->{}#{block})") # LAMBDA + check_allocations(0, 1, "keyword.(*empty_array, a: $1#{block})") # NTH_REF + check_allocations(0, 1, "keyword.(*empty_array, a: $`#{block})") # BACK_REF + RUBY + end + + class WithBlock < self + def block + ', &block' + end + end + end end |