]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blob - t/18-opinfo.t
00133452d76d8acdb0ca8adcb2da5b833aaee0e3
[perl/modules/Variable-Magic.git] / t / 18-opinfo.t
1 #!perl -T
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 19 * (3 + 4) + 5 + 1;
7
8 use Config qw<%Config>;
9
10 use Variable::Magic qw<wizard cast dispell VMG_OP_INFO_NAME VMG_OP_INFO_OBJECT>;
11
12 sub Variable::Magic::TestPkg::foo { }
13
14 my $is_5130_release = ("$]" == 5.013 && !$Config{git_describe}) ? 1 : 0;
15
16 my $aelem     = "$]" <= 5.008_003 ? 'aelem'
17                                   : ("$]" < 5.013 or $is_5130_release)
18                                                    ? 'aelemfast'
19                                   : ("$]" < 5.037_003)
20                                                    ? 'sassign'
21                                                    : 'padsv_store';
22 my $aelemf    = ("$]" < 5.013 or $is_5130_release) ? 'aelemfast'
23                                   : ("$]" < 5.037_003) ? 'sassign'
24                                                        : 'padsv_store';
25
26 my $assign_op    = ("$]" < 5.037_003) ? 'sassign': 'padsv_store';
27 my $assign_op_cl = ("$]" < 5.037_003) ? 'B::BINOP': 'B::UNOP';
28
29 my $aelemf_op = ($aelemf eq 'sassign')     ? 'B::BINOP'
30               : ($aelemf eq 'padsv_store') ? 'B::UNOP'
31               : $Config{useithreads} ? 'B::PADOP' : 'B::SVOP';
32 my $meth_op   = ("$]" < 5.021_005) ? 'B::SVOP' : 'B::METHOP';
33 my $trutf_op  = ($Config{useithreads} && "$]" >= 5.008_009)
34                    ? 'B::PADOP' : 'B::SVOP';
35 my $deref     = ("$]" < 5.021_007) ? 'helem' : 'multideref';
36 my $deref_op  = ($deref eq 'multideref') ? 'B::UNOP_AUX' : 'B::UNOP';
37
38 our @o;
39
40 my @tests = (
41  [ 'len', '@c',      'my @c',    'my $x = @c',     [ 'padav',   'B::OP'     ] ],
42  [ 'get', '$c[0]',   'my @c',    'my $x = $c[0]; 1',
43                                                    [ $aelem,    'B::OP'     ] ],
44  [ 'get', '$o[0]',   'local @o', 'my $x = $o[0]; 1',
45                                                    [ $aelemf,   $aelemf_op  ] ],
46  [ 'get', '$x->{a}', 'my $x',    'my $y = $x->{a}{b}',
47                                                    [ $deref,    $deref_op   ] ],
48  [ 'get', '$c',    'my $c = 1',  '++$c',           [ 'preinc',  'B::UNOP'   ] ],
49  [ 'get', '$c',    'my $c = 1',  '$c ** 2',        [ 'pow',     'B::BINOP'  ] ],
50  [ 'get', '$c',    'my $c = 1',  'my $x = $c; 1',  [ $assign_op, $assign_op_cl ] ],
51  [ 'get', '$c',    'my $c = 1',  '1 if $c',        [ 'and',     'B::LOGOP'  ] ],
52  [ 'get', '$c',    'my $c = []', 'ref $c',         [ 'ref',     'B::UNOP'   ] ],
53  [ 'get', '$c',    'my $c = $0', '-f $c',          [ 'ftfile',  'B::UNOP'   ] ],
54  [ 'get', '$c',    'my $c = "Z"',
55                    'my $i = 1; Z:goto $c if $i--', [ 'goto',    'B::UNOP'   ] ],
56  [ 'set', '$c',    'my $c = 1',  'bless \$c, "main"',
57                                                    [ 'bless',   'B::LISTOP' ] ],
58  [ 'get', '$c',    'my $c = ""', '$c =~ /x/',      [ 'match',   'B::PMOP'   ] ],
59  [ 'get', '$c',    'my $c = "Variable::Magic::TestPkg"',
60                                  '$c->foo()', [ 'method_named', $meth_op    ] ],
61  [ 'get', '$c',    'my $c = ""', '$c =~ y/x/y/',   [ 'trans',   'B::PVOP'   ] ],
62  [ 'get', '$c',    'my $c = ""', '$c =~ y/\x{100}//',
63                                                    [ 'trans',   $trutf_op   ] ],
64  [ 'get', '$c',    'my $c = 1',  '1 for 1 .. $c',
65                                                  [ 'enteriter', 'B::LOOP'   ] ],
66  [ 'free','$c',    'my $c = 1',  'last',           [ 'last',    'B::OP'     ] ],
67  [ 'free','$c', 'L:{my $c = 1',  'last L}',        [ 'last',    'B::OP'     ] ],
68 );
69
70 our $done;
71
72 my $OP_INFO_NAME   = VMG_OP_INFO_NAME;
73 my $OP_INFO_OBJECT = VMG_OP_INFO_OBJECT;
74
75 for (@tests) {
76  my ($key, $var, $init, $test, $exp) = @$_;
77
78  for my $op_info ($OP_INFO_NAME, $OP_INFO_OBJECT) {
79   my $wiz;
80
81   # We must test for the $op correctness inside the callback because, if we
82   # bring it out, it will go outside of the eval STRING scope, and what it
83   # points to will no longer exist.
84   eval {
85    $wiz = wizard $key => sub {
86     return if $done;
87     my $op = $_[-1];
88     my $desc = "$key magic with op_info == $op_info";
89     if ($op_info == $OP_INFO_NAME) {
90      is $op, $exp->[0], "$desc gets the right op info";
91     } elsif ($op_info == $OP_INFO_OBJECT) {
92      isa_ok $op, $exp->[1], $desc;
93      is $op->name, $exp->[0], "$desc gets the right op info";
94     } else {
95      is $op, undef, "$desc gets the right op info";
96     }
97     $done = 1;
98     ()
99    }, op_info => $op_info
100   };
101   is $@, '', "$key wizard with op_info == $op_info doesn't croak";
102
103   local $done = 0;
104
105   my $testcase = "{ $init; cast $var, \$wiz; $test }";
106
107   eval $testcase;
108   is $@, '', "$key magic with op_info == $op_info doesn't croak";
109   diag $testcase if $@;
110  }
111 }
112
113 {
114  my $c;
115
116  my $wiz = eval {
117   wizard get => sub {
118     is $_[-1], undef, 'get magic with out of bounds op_info';
119    },
120    op_info => 3;
121  };
122  is $@, '', "get wizard with out of bounds op_info doesn't croak";
123
124  eval { cast $c, $wiz };
125  is $@, '', "get cast with out of bounds op_info doesn't croak";
126
127  eval { my $x = $c };
128  is $@, '', "get magic with out of bounds op_info doesn't croak";
129
130  eval { dispell $c, $wiz };
131  is $@, '', "get dispell with out of bounds op_info doesn't croak";
132 }
133
134 {
135  local $@;
136  my $wiz = eval {
137   local $SIG{__WARN__} = sub { die @_ };
138   wizard op_info => "hlagh";
139  };
140  like $@, qr/^Argument "hlagh" isn't numeric in subroutine entry at \Q$0\E/,
141       'wizard(op_info => "text") throws numeric warnings';
142 }