]> git.vpit.fr Git - perl/modules/autovivification.git/blob - t/lib/autovivification/TestCases.pm
87dfd0965fc81da8b35b0f0b6a5f65823b64af5f
[perl/modules/autovivification.git] / t / lib / autovivification / TestCases.pm
1 package autovivification::TestCases;
2
3 use strict;
4 use warnings;
5
6 use Test::More;
7
8 sub import {
9  no strict 'refs';
10  *{caller().'::testcase_ok'} = \&testcase_ok;
11 }
12
13 sub in_strict { (caller 0)[8] & (eval { strict::bits(@_) } || 0) };
14
15 sub generate {
16  my ($var, $init, $code, $exp, $use, $opts, $global) = @_;
17  my $decl = $global ? "our $var; local $var;" : "my $var;";
18  my $test = $var =~ /^[@%]/ ? "\\$var" : $var;
19  my $desc = join('; ', map { my $x = $_; $x=~ s,;\s*$,,; $x }
20                                    grep /\S/, $decl, $init, $code) . " <$opts>";
21  return <<TESTCASE, $desc;
22 $decl
23 $init
24 my \$strict = autovivification::TestCases::in_strict('refs');
25 my \@exp = ($exp);
26 my \$res = eval {
27  local \$SIG{__WARN__} = sub { die join '', 'warn:', \@_ };
28  $use
29  $code
30 };
31 if (ref \$exp[0]) {
32  like \$@, \$exp[0], \$desc . ' [exception]';
33 } else {
34  is   \$@, \$exp[0], \$desc . ' [exception]';
35 }
36 is_deeply \$res, \$exp[1], \$desc . ' [return]';
37 is_deeply $test, \$exp[2], \$desc . ' [variable]';
38 TESTCASE
39 }
40
41 sub testcase_ok {
42  local $_  = shift;
43  my $sigil = shift;
44  my @chunks = split /#+/, "$_ ";
45  s/^\s+//, s/\s+$// for @chunks;
46  my ($init, $code, $exp, $opts) = @chunks;
47  (my $var = $init) =~ s/[^\$@%\w].*//;
48  $init = $var eq $init ? '' : "$init;";
49  my $use;
50  if ($opts) {
51   for (split ' ', $opts) {
52    my $no = 1;
53    $no = 0 if s/^([-+])// and $1 eq '-';
54    $use .= ($no ? 'no' : 'use') . " autovivification '$_';"
55   }
56  } elsif (defined $opts) {
57   $opts = 'empty';
58   $use  = 'no autovivification;';
59  } else {
60   $opts = 'default';
61   $use  = '';
62  }
63  my @testcases = (
64   [ $var, $init,               $code, $exp, $use, $opts, 0 ],
65   [ $var, "use strict; $init", $code, $exp, $use, $opts, 1 ],
66   [ $var, "no strict;  $init", $code, $exp, $use, $opts, 1 ],
67  );
68  my @extra;
69  for (@testcases) {
70   my $var = $_->[0];
71   if ($var =~ /\$/) {
72    my @new = @$_;
73    $new[0] =~ s/^\$/$sigil/;
74    for ($new[1], $new[2]) {
75     s/\Q$sigil$var\E/$new[0]/g;
76     s/\Q$var\E\->/$var/g;
77    }
78    my $simple      = $new[2] !~ /->/;
79    my $plain_deref = $new[2] =~ /\Q$new[0]\E/;
80    my $empty  = { '@' => '[ ]', '%' => '{ }' }->{$sigil};
81    if (($simple
82         and (   $new[3] =~ m!qr/\^Reference vivification forbidden.*?/!
83              or $new[3] =~ m!qr/\^Can't vivify reference.*?/!))
84     or ($plain_deref
85         and $new[3] =~ m!qr/\^Can't use an undefined value as a.*?/!)) {
86     $new[1] = '';
87     $new[2] = 1;
88     $new[3] = "'', 1, $empty";
89    }
90    $new[3] =~ s/,\s*undef\s*$/, $empty/;
91    push @extra, \@new;
92   }
93  }
94  push @testcases, @extra;
95  for (@testcases) {
96   my ($testcase, $desc) = generate(@$_);
97   my @N = (0 .. 9);
98   eval $testcase;
99   diag "== This testcase failed to compile ==\n$testcase\n## Reason: $@" if $@;
100  }
101 }
102
103 1;