]> git.vpit.fr Git - perl/modules/Variable-Magic.git/commitdiff
Test timely destruction of values returned from magic callbacks
authorVincent Pit <vince@profvince.com>
Mon, 20 Jul 2015 16:32:52 +0000 (13:32 -0300)
committerVincent Pit <vince@profvince.com>
Mon, 20 Jul 2015 16:32:52 +0000 (13:32 -0300)
t/80-leaks.t

index 7b2a3f0ed51d44ec3ddd9d6a693104cb907a1b8e..6916936327e0ad0c2c3c2e626c791296eefc22ce 100644 (file)
@@ -3,9 +3,15 @@
 use strict;
 use warnings;
 
-use Test::More tests => 11;
+use Variable::Magic qw<wizard cast getdata dispell MGf_LOCAL VMG_UVAR>;
 
-use Variable::Magic qw<wizard cast getdata>;
+use Test::More;
+
+BEGIN {
+ my $tests = 11;
+ $tests += 3 * (4 + (MGf_LOCAL ? 1 : 0) + (VMG_UVAR ? 4 : 0));
+ plan tests => $tests;
+}
 
 our $destroyed;
 
@@ -89,3 +95,65 @@ sub D () { 'Variable::Magic::TestDestructor' }
 
  is $destroyed, 1;
 }
+
+# Test destruction of returned values
+
+my @methods = qw<get set clear free>;
+push @methods, 'local' if MGf_LOCAL;
+push @methods, qw<fetch store exists delete> if VMG_UVAR;
+
+my %init = (
+ scalar_lexical => 'my $x = 1; cast $x, $w',
+ scalar_global  => 'our $X; local $X = 1; cast $X, $w',
+ array          => 'my @a = (1); cast @a, $w',
+ hash           => 'my %h = (a => 1); cast %h, $w',
+);
+
+my %type;
+$type{$_} = 'scalar_lexical' for qw<get set free>;
+$type{$_} = 'scalar_global'  for qw<local>;
+$type{$_} = 'array'          for qw<clear>;
+$type{$_} = 'hash'           for qw<fetch store exists delete>;
+
+my %trigger = (
+ get    => 'my $y = $x',
+ set    => '$x = 2',
+ clear  => '@a = ()',
+ free   => '',
+ local  => 'local $X = 2',
+ fetch  => 'my $v = $h{a}',
+ store  => '$h{a} = 2',
+ exists => 'my $e = exists $h{a}',
+ delete => 'my $d = delete $h{a}',
+);
+
+for my $meth (@methods) {
+ local $destroyed = 0;
+
+ {
+  my $w = wizard $meth => sub { return D->new };
+
+  my $init    = $init{$type{$meth}};
+  my $trigger = $trigger{$meth};
+
+  if ($meth eq 'free') {
+   $init    = "{\n$init";
+   $trigger = '}';
+  }
+
+  my $code = join ";\n", grep length, (
+   $init,
+   'is $destroyed, 0, "return from $meth, before trigger"',
+   $trigger,
+   'is $destroyed, 1, "return from $meth, after trigger"',
+  );
+
+  {
+   local $@;
+   eval $code;
+   die $@ if $@;
+  }
+
+  is $destroyed, 1, "return from $meth, end";
+ }
+}