]> git.vpit.fr Git - perl/modules/Variable-Magic.git/commitdiff
Test when magic actions take place
authorVincent Pit <vince@profvince.com>
Sat, 21 Mar 2009 23:44:33 +0000 (00:44 +0100)
committerVincent Pit <vince@profvince.com>
Sat, 21 Mar 2009 23:44:33 +0000 (00:44 +0100)
MANIFEST
lib/Variable/Magic.pm
t/20-get.t
t/21-set.t
t/22-len.t
t/23-clear.t
t/25-copy.t
t/28-uvar.t
t/lib/Variable/Magic/TestValue.pm [new file with mode: 0644]

index 368099069959f4d27aff138bf8b2e4fa74e892e9..d64a46480d408b3e825bbf7f9ecb4d82019468c2 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -43,4 +43,5 @@ t/92-pod-coverage.t
 t/95-portability-files.t
 t/99-kwalitee.t
 t/lib/Variable/Magic/TestDieRequired.pm
+t/lib/Variable/Magic/TestValue.pm
 t/lib/Variable/Magic/TestWatcher.pm
index 9e24440331643d8857c1f19824f68e90d9380f6e..b588e88070fb5f6d6ef56de515d24e4d69fd5f4c 100644 (file)
@@ -72,8 +72,8 @@ You attach it to variables, not values (as for blessed references).
 
 It doesn't replace the original semantics.
 
-Magic callbacks trigger before the original action take place, and can't prevent it to happen.
-This makes catching individual events easier than with C<tie>, where you have to provide fallbacks methods for all actions by usually inheriting from the correct C<Tie::Std*> class and overriding individual methods in your own class.
+Magic callbacks usually trigger before the original action take place, and can't prevent it to happen.
+This also makes catching individual events easier than with C<tie>, where you have to provide fallbacks methods for all actions by usually inheriting from the correct C<Tie::Std*> class and overriding individual methods in your own class.
 
 =item *
 
index 7548e15e20adfef567fac84fa407063e64755b00..659007066bfd6f870b20e8f1df0150e76123f098 100644 (file)
@@ -3,12 +3,13 @@
 use strict;
 use warnings;
 
-use Test::More tests => 2 * 4 + 2 + 1;
+use Test::More tests => (2 * 4 + 2) + (2 * 2) + 1;
 
 use Variable::Magic qw/cast/;
 
 use lib 't/lib';
 use Variable::Magic::TestWatcher;
+use Variable::Magic::TestValue;
 
 my $wiz = init_watcher 'get', 'get';
 
@@ -24,3 +25,11 @@ is $b, $n, 'get: assign to correctly';
 
 $b = watch { "X${a}Y" } { get => 1 }, 'interpolate';
 is $b, "X${n}Y", 'get: interpolate correctly';
+
+{
+ my $val = 0;
+
+ init_value $val, 'get', 'get';
+
+ value { my $x = $val } \0;
+}
index 5ed992fe5577145a14b32aa4d788664308b77c4f..25535e26d026503e64c970e3a236b8cdcadd977d 100644 (file)
@@ -3,12 +3,13 @@
 use strict;
 use warnings;
 
-use Test::More tests => 2 * 5 + 3 + 1;
+use Test::More tests => (2 * 5 + 3) + (2 * 2 + 1);
 
 use Variable::Magic qw/cast/;
 
 use lib 't/lib';
 use Variable::Magic::TestWatcher;
+use Variable::Magic::TestValue;
 
 my $wiz = init_watcher 'set', 'set';
 
@@ -26,3 +27,11 @@ is $a, $n + 1, 'set: increment correctly';
 
 watch { --$a } { set => 1 }, 'decrement';
 is $a, $n, 'set: decrement correctly';
+
+{
+ my $val = 0;
+
+ init_value $val, 'set', 'set';
+
+ value { $val = 1 } \1;
+}
index 3b8039efc1f926af430c4c5da0eda14235d5aa19..7025e7bb1ffce743f0d70f5a83aef9a72dec3cac 100644 (file)
@@ -3,9 +3,12 @@
 use strict;
 use warnings;
 
-use Test::More tests => 33;
+use Test::More tests => 33 + (2 * 2 + 1);
 
-use Variable::Magic qw/wizard cast VMG_COMPAT_SCALAR_LENGTH_NOLEN/;
+use Variable::Magic qw/wizard cast dispell VMG_COMPAT_SCALAR_LENGTH_NOLEN/;
+
+use lib 't/lib';
+use Variable::Magic::TestValue;
 
 my $c = 0;
 
@@ -124,3 +127,14 @@ SKIP: {
  is $d, 5,  'len: get utf8 scalar length have correct default length';
  is $b, $d, 'len: get utf8 scalar length correctly';
 }
+
+{
+ my @val = (4 .. 6);
+
+ my $wv = init_value @val, 'len', 'len';
+
+ value { $val[-1] = 8 } [ 4, 5, 6 ];
+
+ dispell @val, $wv;
+ is_deeply \@val, [ 4, 5, 8 ], 'len: after value';
+}
index 3f7f57e7ed8d0928b4a5db1c36aa65ad93352ea7..a3aad82ded0d9e07f14c90ac9ab46600e07163ab 100644 (file)
@@ -3,12 +3,13 @@
 use strict;
 use warnings;
 
-use Test::More tests => 2 * 5 + 2 + 1;
+use Test::More tests => (2 * 5 + 2) + (2 * 2 + 1) + 1;
 
-use Variable::Magic qw/cast/;
+use Variable::Magic qw/cast dispell/;
 
 use lib 't/lib';
 use Variable::Magic::TestWatcher;
+use Variable::Magic::TestValue;
 
 my $wiz = init_watcher 'clear', 'clear';
 
@@ -25,3 +26,14 @@ watch { cast %h, $wiz } { }, 'cast hash';
 
 watch { %h = () } { clear => 1 }, 'clear hash';
 is_deeply \%h, { }, 'clear: clear hash correctly';
+
+{
+ my @val = (4 .. 6);
+
+ my $wv = init_value @val, 'clear', 'clear';
+
+ value { @val = () } [ 4 .. 6 ];
+
+ dispell @val, $wv;
+ is_deeply \@val, [ ], 'clear: value after';
+}
index 5ebcbe03406b17a61f63ecba11f7dc00738e3077..98fbf22d3fcdf378e417ee675e031393dd9b0a1c 100644 (file)
@@ -5,22 +5,24 @@ use warnings;
 
 use Test::More;
 
-use Variable::Magic qw/cast MGf_COPY/;
+use Variable::Magic qw/cast dispell MGf_COPY/;
 
 if (MGf_COPY) {
- plan tests => 2 + (2 * 5 + 3) + (2 * 9 + 6) + 1;
+ plan tests => 2 + ((2 * 5 + 3) + (2 * 2 + 1)) + (2 * 9 + 6) + 1;
 } else {
  plan skip_all => 'No copy magic for this perl';
 }
 
 use lib 't/lib';
 use Variable::Magic::TestWatcher;
+use Variable::Magic::TestValue;
 
 my $wiz = init_watcher 'copy', 'copy';
 
 SKIP: {
  eval "use Tie::Array";
- skip 'Tie::Array required to test copy magic on arrays', 2 * 5 + 3 if $@;
+ skip 'Tie::Array required to test copy magic on arrays'
+                                             => (2 * 5 + 3) + (2 * 2 + 1) if $@;
  diag "Using Tie::Array $Tie::Array::VERSION" if defined $Tie::Array::VERSION;
 
  tie my @a, 'Tie::StdArray';
@@ -38,6 +40,18 @@ SKIP: {
  ok $s, 'copy: tied array exists correctly';
 
  watch { undef @a } { }, 'tied array undef';
+
+ {
+  tie my @val, 'Tie::StdArray';
+  @val = (4 .. 6);
+
+  my $wv = init_value @val, 'copy', 'copy';
+
+  value { $val[3] = 8 } [ 4 .. 6 ];
+
+  dispell @val, $wv;
+  is_deeply \@val, [ 4 .. 6, 8 ], 'copy: value after';
+ }
 }
 
 SKIP: {
index 65f685b032b79ba88b7e1b33fab39f2fbb02b3fd..b0114ad67f5234b3d960f3f785c5eb609923dc10 100644 (file)
@@ -8,13 +8,14 @@ use Test::More;
 use Variable::Magic qw/wizard cast dispell VMG_UVAR/;
 
 if (VMG_UVAR) {
- plan tests => 2 * 15 + 12 + 14 + 1;
+ plan tests => 2 * 15 + 12 + 14 + (4 * 2 * 2 + 1 + 1) + 1;
 } else {
  plan skip_all => 'No nice uvar magic for this perl';
 }
 
 use lib 't/lib';
 use Variable::Magic::TestWatcher;
+use Variable::Magic::TestValue;
 
 my $wiz = init_watcher [ qw/fetch store exists delete/ ], 'uvar';
 
@@ -109,3 +110,41 @@ for my $i (1 .. 2) {
  is_deeply \%h3, { a => 3, b => 5, c => 5 + $i },
                         "uvar: change readonly key in store correcty ($i)";
 }
+
+{
+ my %val = (apple => 1);
+
+ init_value %val, 'fetch', 'uvar';
+
+ value { my $x = $val{apple} } { apple => 1 }, 'value store';
+}
+
+{
+ my %val = (apple => 1);
+
+ my $wv = init_value %val, 'store', 'uvar';
+
+ value { $val{apple} = 2 } { apple => 1 }, 'value store';
+
+ dispell %val, $wv;
+ is_deeply \%val, { apple => 2 }, 'uvar: value after store';
+}
+
+{
+ my %val = (apple => 1);
+
+ init_value %val, 'exists', 'uvar';
+
+ value { my $x = exists $val{apple} } { apple => 1 }, 'value exists';
+}
+
+{
+ my %val = (apple => 1, banana => 2);
+
+ my $wv = init_value %val, 'delete', 'uvar';
+
+ value { delete $val{apple} } { apple => 1, banana => 2 }, 'value delete';
+
+ dispell %val, $wv;
+ is_deeply \%val, { banana => 2 }, 'uvar: value after delete';
+}
diff --git a/t/lib/Variable/Magic/TestValue.pm b/t/lib/Variable/Magic/TestValue.pm
new file mode 100644 (file)
index 0000000..491055f
--- /dev/null
@@ -0,0 +1,55 @@
+package Variable::Magic::TestValue;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use Variable::Magic qw/wizard cast/;
+
+use base qw/Exporter/;
+
+our @EXPORT = qw/init_value value/;
+
+our ($exp, $prefix, $desc);
+
+sub value_cb {
+ my $data = $_[1];
+ return if $data->{guard};
+ local $data->{guard} = 1;
+ local $Test::Builder::Level = ($Test::Builder::Level || 0) + 3;
+ is_deeply $_[0], $exp, $desc;
+ ()
+}
+
+sub init_value (\[$@%&*]$;$) {
+ my $type = $_[1];
+ $prefix  = (defined) ? "$_: " : '' for $_[2];
+ my $wiz  = eval "wizard data => sub { +{ guard => 0 } }, $type => \\&value_cb";
+ is $@, '', $prefix . 'wizard() doesn\'t croak';
+ eval { &cast($_[0], $wiz, $prefix) };
+ is $@, '', $prefix . 'cast() doesn\'t croak';
+ return $wiz;
+}
+
+sub value (&$;$) {
+ my ($code, $_exp, $_desc) = @_;
+ my $want = wantarray;
+ $_desc = 'value' unless defined $desc;
+ $_desc = $prefix . $_desc;
+ my @ret;
+ {
+  local $Test::Builder::Level = ($Test::Builder::Level || 0) + 1;
+  local $exp  = $_exp;
+  local $desc = $_desc;
+  if (defined $want and not $want) { # scalar context
+   $ret[0] = eval { $code->() };
+  } else {
+   @ret = eval { $code->() };
+  }
+  is $@, '', $desc . ' doesn\'t croak';
+ }
+ return $want ? @ret : $ret[0];
+}
+
+1;