]> git.vpit.fr Git - perl/modules/Scope-Upper.git/blobdiff - t/40-localize_delete-target.t
Protect against d_cplusplus perls
[perl/modules/Scope-Upper.git] / t / 40-localize_delete-target.t
index 30468a1169ee13df4d85ae45c27ea5e435791769..26a81952010a26c7a3e43b16c7329f0a56e949af 100644 (file)
@@ -3,9 +3,9 @@
 use strict;
 use warnings;
 
-use Test::More tests => 36;
+use Test::More tests => 53 + 4;
 
-use Scope::Upper qw/localize_delete/;
+use Scope::Upper qw<localize_delete UP HERE>;
 
 # Arrays
 
@@ -14,57 +14,57 @@ our @a;
 {
  local @a = (4 .. 6);
  {
-  localize_delete '@main::a', 1, 0;
-  is_deeply \@a, [ 4, undef, 6 ], 'localize_delete "@a", 1, 0 [ok]';
+  localize_delete '@main::a', 1 => HERE;
+  is_deeply \@a, [ 4, undef, 6 ], 'localize_delete "@a", 1 => HERE [ok]';
  }
- is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 1, 0 [end]';
+ is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 1 => HERE [end]';
 }
 
 {
  local @a = (4 .. 6);
  {
-  localize_delete '@main::a', 4, 0;
-  is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (nonexistent), 0 [ok]';
+  localize_delete '@main::a', 4 => HERE;
+  is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (nonexistent) => HERE [ok]';
  }
- is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (nonexistent), 0 [end]';
+ is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (nonexistent) => HERE [end]';
 }
 
 {
  local @a = (4 .. 6);
  local $a[4] = 7;
  {
-  localize_delete '@main::a', 4, 0;
-  is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (exists), 0 [ok]';
+  localize_delete '@main::a', 4 => HERE;
+  is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (exists) => HERE [ok]';
  }
- is_deeply \@a, [ 4 .. 6, undef, 7 ], 'localize_delete "@a", 4 (exists), 0 [end]';
+ is_deeply \@a, [ 4 .. 6, undef, 7 ], 'localize_delete "@a", 4 (exists) => HERE [end]';
 }
 
 {
  local @a = (4 .. 6);
  {
-  localize_delete '@main::a', -2, 0;
-  is_deeply \@a, [ 4, undef, 6 ], 'localize_delete "@a", -2, 0 [ok]';
+  localize_delete '@main::a', -2 => HERE;
+  is_deeply \@a, [ 4, undef, 6 ], 'localize_delete "@a", -2 => HERE [ok]';
  }
- is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", -2, 0 [end]';
+ is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", -2 => HERE [end]';
 }
 
 {
  local @a = (4 .. 6);
  local $a[4] = 7;
  {
-  localize_delete '@main::a', -1, 0;
-  is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", -1 (exists), 0 [ok]';
+  localize_delete '@main::a', -1 => HERE;
+  is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", -1 (exists) => HERE [ok]';
  }
- is_deeply \@a, [ 4 .. 6, undef, 7 ], 'localize_delete "@a", -1 (exists), 0 [end]';
+ is_deeply \@a, [ 4 .. 6, undef, 7 ], 'localize_delete "@a", -1 (exists) => HERE [end]';
 }
 
 {
  local @a = (4 .. 6);
  {
-  eval { localize_delete '@main::a', -4, 0 };
-  like $@, qr/Modification of non-creatable array value attempted, subscript -4/, 'localize_delete "@a", -4 (out of bounds), 0 [ok]';
+  eval { localize_delete '@main::a', -4 => HERE };
+  like $@, qr/Modification of non-creatable array value attempted, subscript -4/, 'localize_delete "@a", -4 (out of bounds) => HERE [ok]';
  }
- is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", -4 (out of bounds), 0 [end]';
+ is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", -4 (out of bounds) => HERE [end]';
 }
 
 {
@@ -72,12 +72,12 @@ our @a;
  {
   local @a = (5 .. 7);
   {
-   localize_delete '@main::a', 1, 1;
-   is_deeply \@a, [ 5 .. 7 ], 'localize_delete "@a", 1, 1 [not yet]';
+   localize_delete '@main::a', 1 => UP;
+   is_deeply \@a, [ 5 .. 7 ], 'localize_delete "@a", 1 => UP [not yet]';
   }
-  is_deeply \@a, [ 5, undef, 7 ], 'localize_delete "@a", 1, 1 [ok]';
+  is_deeply \@a, [ 5, undef, 7 ], 'localize_delete "@a", 1 => UP [ok]';
  }
- is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 1, 1 [end]';
+ is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 1 => UP [end]';
 }
 
 {
@@ -85,12 +85,12 @@ our @a;
  {
   local @a = (5 .. 7);
   {
-   localize_delete '@main::a', 4, 1;
-   is_deeply \@a, [ 5 .. 7 ], 'localize_delete "@a", 4 (nonexistent), 1 [not yet]';
+   localize_delete '@main::a', 4 => UP;
+   is_deeply \@a, [ 5 .. 7 ], 'localize_delete "@a", 4 (nonexistent) => UP [not yet]';
   }
-  is_deeply \@a, [ 5 .. 7 ], 'localize_delete "@a", 4 (nonexistent), 1 [ok]';
+  is_deeply \@a, [ 5 .. 7 ], 'localize_delete "@a", 4 (nonexistent) => UP [ok]';
  }
- is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (nonexistent), 1 [end]';
+ is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (nonexistent) => UP [end]';
 }
 
 {
@@ -99,12 +99,22 @@ our @a;
   local @a = (5 .. 7);
   local $a[4] = 8;
   {
-   localize_delete '@main::a', 4, 1;
-   is_deeply \@a, [ 5 .. 7, undef, 8 ], 'localize_delete "@a", 4 (exists), 1 [not yet]';
+   localize_delete '@main::a', 4 => UP;
+   is_deeply \@a, [ 5 .. 7, undef, 8 ], 'localize_delete "@a", 4 (exists) => UP [not yet]';
   }
-  is_deeply \@a, [ 5 .. 7 ], 'localize_delete "@a", 4 (exists), 1 [ok]';
+  is_deeply \@a, [ 5 .. 7 ], 'localize_delete "@a", 4 (exists) => UP [ok]';
  }
- is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (exists), 1 [end]';
+ is_deeply \@a, [ 4 .. 6 ], 'localize_delete "@a", 4 (exists) => UP [end]';
+}
+
+{
+ {
+  localize_delete '@nonexistent', 2;
+  is_deeply eval('*nonexistent{ARRAY}'), [ ],
+                       'localize_delete "@nonexistent", anything => HERE [ok]';
+ }
+ is_deeply eval('*nonexistent{ARRAY}'), [ ],
+                       'localize_delete "@nonexistent", anything => HERE [end]';
 }
 
 # Hashes
@@ -114,19 +124,19 @@ our %h;
 {
  local %h = (a => 1, b => 2);
  {
-  localize_delete '%main::h', 'a', 0;
-  is_deeply \%h, { b => 2 }, 'localize_delete "%h", "a", 0 [ok]';
+  localize_delete '%main::h', 'a' => HERE;
+  is_deeply \%h, { b => 2 }, 'localize_delete "%h", "a" => HERE [ok]';
  }
- is_deeply \%h, { a => 1, b => 2 }, 'localize_delete "%h", "a", 0 [end]';
+ is_deeply \%h, { a => 1, b => 2 }, 'localize_delete "%h", "a" => HERE [end]';
 }
 
 {
  local %h = (a => 1, b => 2);
  {
-  localize_delete '%main::h', 'c', 0;
-  is_deeply \%h, { a => 1, b => 2 }, 'localize_delete "%h", "c", 0 [ok]';
+  localize_delete '%main::h', 'c' => HERE;
+  is_deeply \%h, { a => 1, b => 2 }, 'localize_delete "%h", "c" => HERE [ok]';
  }
- is_deeply \%h, { a => 1, b => 2 }, 'localize_delete "%h", "c", 0 [end]';
+ is_deeply \%h, { a => 1, b => 2 }, 'localize_delete "%h", "c" => HERE [end]';
 }
 
 {
@@ -134,34 +144,134 @@ our %h;
  {
   local %h = (a => 3, c => 4);
   {
-   localize_delete '%main::h', 'a', 1;
-   is_deeply \%h, { a => 3, c => 4 }, 'localize_delete "%h", "a", 1 [not yet]';
+   localize_delete '%main::h', 'a' => UP;
+   is_deeply \%h, { a => 3, c => 4 }, 'localize_delete "%h", "a" => UP [not yet]';
   }
-  is_deeply \%h, { c => 4 }, 'localize_delete "%h", "a", 1 [ok]';
+  is_deeply \%h, { c => 4 }, 'localize_delete "%h", "a" => UP [ok]';
+ }
+ is_deeply \%h, { a => 1, b => 2 }, 'localize_delete "%h", "a" => UP [end]';
+}
+
+{
+ {
+  localize_delete '%nonexistent', 'a';
+  is_deeply eval('*nonexistent{HASH}'), { },
+                       'localize_delete "%nonexistent", anything => HERE [ok]';
  }
- is_deeply \%h, { a => 1, b => 2 }, 'localize_delete "%h", "a", 1 [end]';
+ is_deeply eval('*nonexistent{HASH}'), { },
+                       'localize_delete "%nonexistent", anything => HERE [end]';
 }
 
-# Others
+# Scalars
 
 our $x = 1;
 {
- localize_delete '$x', 2, 0;
- is $x, undef, 'localize "$x", anything, 0 [ok]';
+ localize_delete '$x', 2 => HERE;
+ is $x, undef, 'localize_delete "$x", anything => HERE [ok]';
+}
+is $x, 1, 'localize_delete "$x", anything => HERE [end]';
+
+{
+ {
+  localize_delete '$nonexistent', 2;
+  is eval('${*nonexistent{SCALAR}}'), undef,
+                       'localize_delete "$nonexistent", anything => HERE [ok]';
+ }
+ is eval('${*nonexistent{SCALAR}}'), undef,
+                       'localize_delete "$nonexistent", anything => HERE [end]';
 }
-is $x, 1, 'localize "$x", anything, 0 [end]';
+
+# Code
 
 sub x { 1 };
 {
- localize_delete '&x', 2, 0;
- ok !exists(&x), 'localize "&x", anything, 0 [ok]';
+ localize_delete '&x', 2 => HERE;
+ ok !exists(&x), 'localize_delete "&x", anything => HERE [ok]';
+}
+is x(), 1, 'localize_delete "&x", anything => HERE [end]';
+
+{
+ {
+  localize_delete '&nonexistent', 2;
+  is eval('exists &nonexistent'), !1,
+                       'localize_delete "&nonexistent", anything => HERE [ok]';
+ }
+ is eval('exists &nonexistent'), !1,
+                       'localize_delete "&nonexistent", anything => HERE [end]';
+}
+
+{
+ localize_delete *x, sub { } => HERE;
+ is !exists(&x),  1, 'localize_delete *x, anything => HERE [ok 1]';
+ is !defined($x), 1, 'localize_delete *x, anything => HERE [ok 2]';
+}
+is x(), 1, 'localize_delete *x, anything => HERE [end 1]';
+is $x,  1, 'localize_delete *x, anything => HERE [end 2]';
+
+sub X::foo { 'X::foo' }
+
+{
+ {
+  {
+   localize_delete '&X::foo', undef => UP;
+   is(X->foo(), 'X::foo', 'localize_delete "&X::foo", undef => UP [not yet X]');
+  }
+  ok(!X->can('foo'), 'localize_delete "&X::foo", undef => UP [ok X]');
+ }
+ is(X->foo(), 'X::foo', 'localize_delete "&X::foo", undef => UP [end X]');
+}
+
+@Y::ISA = 'X';
+
+{
+ {
+  {
+   localize_delete '&X::foo', undef => UP;
+   is(Y->foo(), 'X::foo', 'localize_delete "&X::foo", undef => UP [not yet Y]');
+  }
+  ok(!Y->can('foo'), 'localize_delete "&X::foo", undef => UP [ok Y]');
+ }
+ is(Y->foo(), 'X::foo', 'localize_delete "&X::foo", undef => UP [end Y]');
+}
+
+
+{
+ local *Y::foo = sub { 'Y::foo' };
+ {
+  {
+   localize_delete '&Y::foo', undef => UP;
+   is(Y->foo(), 'Y::foo', 'localize_delete "&Y::foo", undef => UP [not yet]');
+  }
+  is(Y->foo(), 'X::foo', 'localize_delete "&Y::foo", undef => UP [ok]');
+ }
+ is(Y->foo(), 'Y::foo', 'localize_delete "&Y::foo", undef => UP [end]');
+}
+
+{
+ # Prevent 'only once' warnings
+ local *Y::foo = *Y::foo;
+}
+
+# Invalid
+
+sub invalid_ref { qr/^Invalid \Q$_[0]\E reference as the localization target/ }
+
+{
+ eval { localize_delete \1, 0 => HERE };
+ like $@, invalid_ref('SCALAR'), 'invalid localize_delete \1, 0 => HERE';
+}
+
+{
+ eval { localize_delete [ ], 0 => HERE };
+ like $@, invalid_ref('ARRAY'),  'invalid localize_delete [ ], 0 => HERE';
+}
+
+{
+ eval { localize_delete { }, 0 => HERE };
+ like $@, invalid_ref('HASH'),   'invalid localize_delete { }, 0 => HERE';
 }
-is x(), 1, 'localize "&x", anything, 0 [end]';
 
 {
- localize_delete *x, sub { }, 0;
- is !exists(&x),  1, 'localize *x, anything, 0 [ok 1]';
- is !defined($x), 1, 'localize *x, anything, 0 [ok 2]';
+ eval { localize_delete sub { }, 0 => HERE };
+ like $@, invalid_ref('CODE'),   'invalid localize_delete sub { }, 0 => HERE';
 }
-is x(), 1, 'localize *x, anything, 0 [end 1]';
-is $x,  1, 'localize *x, anything, 0 [end 2]';