From: Vincent Pit Date: Sat, 8 Sep 2012 17:48:52 +0000 (+0200) Subject: Revamp t/85-stress-unwind.t X-Git-Tag: v0.20~25 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FScope-Upper.git;a=commitdiff_plain;h=c658e7cbf39b28fe652320c64a38f9e7e06ce8cd Revamp t/85-stress-unwind.t Stop using eval() to compute the expected value. This highlighted an issue with how list() was defined. This test now runs about 25% faster. --- diff --git a/t/85-stress-unwind.t b/t/85-stress-unwind.t index fa52bcd..8ee79c6 100644 --- a/t/85-stress-unwind.t +++ b/t/85-stress-unwind.t @@ -8,15 +8,18 @@ use Test::Leaner 'no_plan'; use Scope::Upper qw; -our ($call, @args, $args); +our ($call, @args); $call = sub { my ($height, $level, $i) = @_; $level = $level ? 'UP ' x $level : 'HERE'; - return [ [ "unwind(\@args => $level)\n", '' ] ]; + 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 {', '}->()' ], @@ -24,36 +27,49 @@ 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 ]; + } +} 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 { int rand 10 } 0 .. rand 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), ]; } } @@ -63,6 +79,23 @@ sub gen { 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; @@ -71,13 +104,13 @@ sub runtests { ++$i; no warnings 'void'; my $res = linearize eval $_->[0]; - $res = '*TEST DID NOT COMPILE*' if $@; my $exp; - unless ($@) { - $exp = linearize eval $_->[1]; - $exp = '*REFERENCE DID NOT COMPILE*' if $@; + if ($@) { + $res = '*TEST DID NOT COMPILE*'; + } else { + $exp = expect $_->[1]; } - if ($@ || $res ne $exp) { + if ($res ne $exp) { diag <[0]; @@ -90,7 +123,6 @@ DIAG for ([ ], [ 'A' ], [ qw ]) { @args = @$_; - $args = '(' . join(', ', map "'$_'", @args) . ')'; runtests 0, 0; runtests 0, 1; runtests 1, 0;