7 use Test::Leaner 'no_plan';
9 use Scope::Upper qw<yield HERE SCOPE>;
11 # @_[0 .. $#_] also ought to work, but it sometimes evaluates to nonsense in
12 # scalar context on perl 5.8.5 and below.
14 sub list { wantarray ? @_ : $_[$#_] }
22 '(list map {', # map in scalar context yields the number of elements
38 [ 'scalar(', ')', 's' ],
39 [ 'list(', ')', 'l' ],
42 sub linearize { join ', ', map { defined($_) ? $_ : '(undef)' } @_ }
47 # Don't put closures in empty pads on 5.6.
50 my $capture_outer_pad = "$]" < 5.008 ? "++\$dummy;" : '';
54 for my $block (@blocks) {
55 for my $context (@contexts) {
56 my $source = <<"FRAME";
58 my \$next = shift; $capture_outer_pad
60 unshift \@stack, HERE;
62 (\@{shift \@pre}, \$next->[0]->(\@_))
76 die "$err. Source was :\n$source\n" if $@;
78 push @test_frames, [ $code, $source, $context->[2] ];
86 yield(@_ => $stack[$depth]);
87 }, 'target context from HERE' ],
90 yield(@_ => SCOPE($depth == 0 ? 0 : (2 * ($depth - 1) + 1)));
91 }, 'target context from SCOPE' ],
96 for my $args ([ ], [ 'A' ], [ qw<B C> ]) {
98 for my $frame0 (@test_frames) {
99 for my $frame1 (@test_frames) {
100 for my $frame2 (@test_frames) {
102 $seed += 5; # Coprime with $max_depth
104 for (1 .. $max_depth) {
107 my $l = $seed % $max_depth - 1;
108 push @prepend, [ $i .. ($i + $l) ];
110 my $prepend_str = join ' ', map { '[' . join(' ', @$_) . ']' } @prepend;
111 for my $depth (0 .. $max_depth) {
113 my @cxts = map $_->[2], $frame0, $frame1, $frame2;
115 for (my $i = $depth + 1; $i <= $max_depth; ++$i) {
116 my $c = $cxts[$max_depth - $i];
119 } elsif ($c eq 's') {
120 @exp = @exp ? $exp[-1] : undef;
122 unshift @exp, @{$prepend[$max_depth - $i]};
127 for my $target (@targets) {
129 local @pre = @prepend;
130 my @res = $frame0->[0]->($frame1, $frame2, $target, @args, $depth);
131 my $got = linearize @res;
134 === This testcase failed ===
139 ==== vvvvv Errors vvvvvv ===
142 is $got, $exp, "yield to depth $depth with args [@args] and prepending $prepend_str";