X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=t%2F44-multideref.t;fp=t%2F44-multideref.t;h=954b069ccae7b6577e878f2d0ed56fccb74b0dad;hb=2178fb413405abba4e2e56e72853cf287f708ff0;hp=0000000000000000000000000000000000000000;hpb=4e74ad4da8d7152cf6d477fd8de677ba94026e7c;p=perl%2Fmodules%2Fautovivification.git diff --git a/t/44-multideref.t b/t/44-multideref.t new file mode 100644 index 0000000..954b069 --- /dev/null +++ b/t/44-multideref.t @@ -0,0 +1,107 @@ +#!perl -T + +use strict; +use warnings; + +use lib 't/lib'; +use Test::Leaner tests => 3 * 4 * (8 ** 3) * 2; + +my $depth = 3; + +my @prefixes = ( + '', + 'exists ', + 'delete ', +); + +my (@vlex, %vlex, $vrlex); +our (@vgbl, %vgbl, $vrgbl); + +my @heads = ( + '$vlex', # lexical array/hash + '$vgbl', # global array/hash + '$vrlex->', # lexical array/hash reference + '$vrgbl->', # global array/hash reference +); + +my $lex; +our $gbl; + +my @derefs = ( + '[0]', # array const (aelemfast) + '[$lex]', # array lexical + '[$gbl]', # array global + '[$lex+1]', # array complex + '{foo}', # hash const + '{$lex}', # hash lexical + '{$gbl}', # hash global + '{"x$lex"}' # hash complex +); + +sub reset_vars { + (@vlex, %vlex, $vrlex) = (); + (@vgbl, %vgbl, $vrgbl) = (); + $lex = 1; + $gbl = 2; +} + +{ + package autovivification::TestIterator; + + sub new { + my $class = shift; + + my $len = @_; + bless { + len => $len, + max => \@_, + idx => [ (0) x $len ], + }, $class; + } + + sub next { + my $self = shift; + + my ($len, $max, $idx) = @$self{qw}; + + my $i; + ++$idx->[0]; + for ($i = 0; $i < $len; ++$i) { + if ($idx->[$i] == $max->[$i]) { + $idx->[$i] = 0; + ++$idx->[$i + 1] unless $i == $len - 1; + } else { + last; + } + } + + return $i < $len; + } + + sub pick { + my $self = shift; + + my ($len, $idx) = @$self{qw}; + + return map $_[$_]->[$idx->[$_]], 0 .. ($len - 1); + } +} + +my $iterator = autovivification::TestIterator->new(3, 4, (8) x $depth); +do { + my @elems = $iterator->pick(\@prefixes, \@heads, (\@derefs) x $depth); + my $code = join '', @elems; + my $exp = $elems[0] eq 'exists ' ? !1 : undef; + reset_vars(); + my ($res, $err) = do { + local $SIG{__WARN__} = sub { die @_ }; + local $@; + my $r = eval <<" CODE"; + no autovivification; + $code + CODE + ($r, $@) + }; + is $err, '', "$code: no exception"; + is $res, $exp, "$code: value"; +} while ($iterator->next);