X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=t%2F85-stress-unwind.t;h=acd44521984471b05fbd0712838da7d3d0f3e0cc;hb=d3fe85111edf0d4cbd702f67eea3bf359bd8b485;hp=75bad3e18dbefe98b3a409c4cb496d7d161cbfaf;hpb=f912774248aa5a4bf3727e5b0315fccf42b96bf3;p=perl%2Fmodules%2FScope-Upper.git diff --git a/t/85-stress-unwind.t b/t/85-stress-unwind.t index 75bad3e..acd4452 100644 --- a/t/85-stress-unwind.t +++ b/t/85-stress-unwind.t @@ -3,18 +3,23 @@ use strict; use warnings; -use Test::More 'no_plan'; +use lib 't/lib'; +use Test::Leaner 'no_plan'; -use Scope::Upper qw/unwind/; +use Scope::Upper qw; -our ($call, @args, $args); +our ($call, @args); $call = sub { my ($height, $level, $i) = @_; - return [ [ "unwind(\@args => $level)\n", '' ] ]; + $level = $level ? 'UP ' x $level : 'HERE'; + return [ [ "unwind(\@args => $level)\n", [ \@args ] ] ]; }; -sub list { @_ } +# @_[0 .. $#_] also ought to work, but it sometimes evaluates to nonsense in +# scalar context on perl 5.8.5 and below. + +sub list { wantarray ? @_ : $_[$#_] } my @blocks = ( [ 'sub {', '}->()' ], @@ -22,36 +27,52 @@ my @blocks = ( ); my @contexts = ( - [ '', '; ()' ], - [ 'scalar(', ')' ], - [ 'list(', ')' ], + [ '', '; ()', 'v' ], + [ 'scalar(', ')', 's' ], + [ 'list(', ')', 'l' ], ); -@blocks = map [ map "$_\n", @$_ ], @blocks; -@contexts = map [ map "$_\n", @$_ ], @contexts; +for my $block (@blocks) { + $_ .= "\n" for @$block[0, 1]; +} +for my $cxt (@contexts) { + $_ .= "\n" for @$cxt[0, 1]; +} + +sub contextify { + my ($cxt, $active, $exp, @items) = @_; + return $exp unless $active; + if ($cxt eq 'v') { + return [ ]; + } elsif ($cxt eq 's') { + return [ $cxt, @$exp ]; + } else { + return [ @items, @$exp ]; + } +} + +my $integer = 0; +my $items = 0; sub gen { my ($height, $level, $i) = @_; push @_, $i = 0 if @_ == 2; my @res; my $up = $i == $height + 1 ? $call->(@_) : gen($height, $level, $i + 1); - if ($i + $level == $height + 1) { - for (@$up) { - $_->[1] = "return($args)\n"; - } - } + my $active = $i <= ($height - $level); for my $base (@$up) { my ($code, $exp) = @$base; for my $blk (@blocks) { for my $cx (@contexts) { push @res, [ $blk->[0] . $cx->[0] . $code . $cx->[1] . $blk->[1], - $blk->[0] . $cx->[0] . $exp . $cx->[1] . $blk->[1], + contextify($cx->[2], $active, $exp), ]; - my $list = join ', ', map { int rand 10 } 0 .. rand 3; + my @items = map $integer++, 0 .. ($items++ % 3); + my $list = join ', ', @items; push @res, [ - $blk->[0] . $cx->[0] . "($list, " . $code . ')' . $cx->[1] . $blk->[1], - $blk->[0] . $cx->[0] . "($list, " . $exp . ')' . $cx->[1] . $blk->[1], + $blk->[0] . $cx->[0] . "($list, $code)" . $cx->[1] . $blk->[1], + contextify($cx->[2], $active, $exp, @items), ]; } } @@ -59,27 +80,52 @@ sub gen { return \@res; } +sub linearize { join ', ', map { defined($_) ? $_ : '(undef)' } @_ } + +sub expect { + my @spec = @{$_[0]}; + my @acc; + for my $s (reverse @spec) { + if (ref $s) { + unshift @acc, @$s; + } elsif ($s =~ /^[0-9]+$/) { + unshift @acc, $s; + } elsif ($s eq 's') { + @acc = (@acc ? $acc[-1] : undef); + } else { + return 'XXX'; + } + } + return linearize @acc; +} + sub runtests { + my ($height, $level) = @_; + my $i; my $tests = gen @_; for (@$tests) { + ++$i; no warnings 'void'; - my @res = eval $_->[0]; - my @exp = eval $_->[1] unless $@; - if ($@ || !is_deeply \@res, \@exp) { - diag "=== vvv Test vvv ==="; - diag $_->[0]; - diag "------- Got --------"; - diag join(', ', map { defined($_) ? $_ : '(undef)' } @res); - diag "----- Expected -----"; - diag join(', ', map { defined($_) ? $_ : '(undef)' } @exp); - diag "=== ^^^^^^^^^^^^ ==="; + my $res = linearize eval $_->[0]; + my $exp; + if ($@) { + $res = '*TEST DID NOT COMPILE*'; + } else { + $exp = expect $_->[1]; + } + if ($res ne $exp) { + diag <[0]; +==== vvvvv Errors vvvvvv === +DIAG } + is $res, $exp, "stress unwind $height $level $i"; } } -for ([ ], [ 'A' ], [ qw/B C/ ]) { +for ([ ], [ 'A' ], [ qw ]) { @args = @$_; - $args = '(' . join(', ', map "'$_'", @args) . ')'; runtests 0, 0; runtests 0, 1; runtests 1, 0;