]> git.vpit.fr Git - perl/modules/Scope-Upper.git/blobdiff - t/20-localize-target.t
Always apply localizations at the glob level
[perl/modules/Scope-Upper.git] / t / 20-localize-target.t
index 56ebd978df5f747f571b6585808ddbb1dda2eb76..e16fa4c80d7991a83f9d7c401225161fce1ac71e 100644 (file)
@@ -3,9 +3,9 @@
 use strict;
 use warnings;
 
-use Test::More tests => 50;
+use Test::More tests => 70 + 2 * 5 + 4;
 
-use Scope::Upper qw/localize UP HERE/;
+use Scope::Upper qw<localize UP HERE>;
 
 # Scalars
 
@@ -32,14 +32,17 @@ sub _t { shift->{t} }
  is $x, undef, 'localize *x, obj => HERE [end]';
 }
 
+our $y;
+
 {
- local $x = 2;
+ local $x = 1;
+ local $y = 2;
  {
-  local $x = 3;
-  localize *x, 1 => HERE;
-  is $x, undef, 'localize *x, 1 => HERE [ok]';
+  local $y = 3;
+  localize *x, 'y' => HERE;
+  is $x, 3, "localize *x, 'y' => HERE [ok]";
  }
- is $x, $] < 5.008009 ? undef : 2, 'localize *x, 1 => HERE [end]';
+ is $x, 1, "localize *x, 'y' => HERE [end]";
 }
 undef *x;
 
@@ -63,7 +66,8 @@ undef *x;
 
 SKIP:
 {
- skip 'Can\'t localize through a reference in 5.6' => 2 if $] < 5.008;
+ skip 'Can\'t localize through a reference before 5.8.1' => 2
+                                                            if "$]" < 5.008_001;
  eval q{
   no strict 'refs';
   local ${''} = 9;
@@ -77,7 +81,8 @@ SKIP:
 
 SKIP:
 {
- skip 'Can\'t localize through a reference in 5.6' => 2 if $] < 5.008;
+ skip 'Can\'t localize through a reference before 5.8.1' => 2
+                                                            if "$]" < 5.008_001;
  eval q{
   no strict 'refs';
   local ${''} = 10;
@@ -251,3 +256,139 @@ my $xh = { a => 5, c => 7 };
  }
  is foo(), 8, 'localize "&foo", sub { 8 } => UP [ok]';
 }
+
+{
+ local *foo = sub { 'a' };
+ {
+  {
+   localize *foo, sub { 'b' } => UP;
+   is foo(), 'a', 'localize *foo, sub { "b" } => UP [not yet 1]';
+   {
+    no warnings 'redefine';
+    local *foo = sub { 'c' };
+    is foo(), 'c', 'localize *foo, sub { "b" } => UP [localized 1]';
+   }
+   is foo(), 'a', 'localize *foo, sub { "b" } => UP [not yet 2]';
+  }
+  is foo(), 'b', 'localize *foo, sub { "b" } => UP [ok 1]';
+  {
+   no warnings 'redefine';
+   local *foo = sub { 'd' };
+   is foo(), 'd', 'localize *foo, sub { "b" } => UP [localized 2]';
+  }
+  is foo(), 'b', 'localize *foo, sub { "b" } => UP [ok 2]';
+ }
+ is foo(), 'a', 'localize *foo, sub { "b" } => UP [end]';
+}
+
+{
+ local *foo = sub { 'x' };
+ {
+  {
+   localize *foo, sub { 'y' } => UP;
+   is foo(), 'x', 'localize *foo, sub { "y" } => UP [not yet]';
+  }
+  is foo(), 'y', 'localize *foo, sub { "y" } => UP [ok]';
+  no warnings 'redefine';
+  *foo = sub { 'z' };
+  is foo(), 'z', 'localize *foo, sub { "y" } => UP [replaced]';
+ }
+ is foo(), 'x', 'localize *foo, sub { "y" } => UP [end]';
+}
+
+sub X::foo { 'X::foo' }
+
+{
+ {
+  {
+   localize 'X::foo', sub { 'X::foo 2' } => UP;
+   is(X->foo, 'X::foo', 'localize "X::foo", sub { "X::foo 2" } => UP [not yet]')
+  }
+  is(X->foo, 'X::foo 2', 'localize "X::foo", sub { "X::foo 2" } => UP [ok]');
+ }
+ is(X->foo, 'X::foo', 'localize "X::foo", sub { "X::foo 2" } => UP [end]');
+}
+
+@Y::ISA = 'X';
+
+{
+ {
+  {
+   localize 'X::foo', sub { 'X::foo 3' } => UP;
+   is(Y->foo, 'X::foo', 'localize "X::foo", sub { "X::foo 3" } => UP [not yet]')
+  }
+  is(Y->foo, 'X::foo 3', 'localize "X::foo", sub { "X::foo 3" } => UP [ok]');
+ }
+ is(Y->foo, 'X::foo', 'localize "X::foo", sub { "X::foo 2" } => UP [end]');
+}
+
+{
+ {
+  {
+   localize 'Y::foo', sub { 'Y::foo' } => UP;
+   is(Y->foo, 'X::foo', 'localize "Y::foo", sub { "Y::foo" } => UP [not yet]');
+  }
+  is(Y->foo, 'Y::foo', 'localize "Y::foo", sub { "Y::foo" } => UP [ok]');
+ }
+ is(Y->foo, 'X::foo', 'localize "Y::foo", sub { "Y::foo" } => UP [end]');
+}
+
+# Import
+
+sub is_imported {
+ my ($pkg, $sig, $val) = @_;
+ my $exp  = $sig eq '$' ? \$val : $val;
+ my $var  = 'daffodil'; # don't use 'x' or eval will capture $main::x
+ my $spec = $sig . $pkg . '::' . $var;
+ localize $spec, $val => HERE;
+ {
+  my $desc = "localize imported ${sig}${var} to $val";
+  my $got  = eval "package $pkg; \\${sig}${var}";
+  if ($@) {
+   fail "$desc test did not compile: $@";
+  } else {
+   is_deeply $got, $exp, $desc;
+  }
+ }
+ {
+  my $desc = "localize defined ${sig}${var} to $val";
+  my $got  = eval "\\${sig}${pkg}::${var}";
+  if ($@) {
+   fail "$desc test did not compile: $@";
+  } else {
+   is_deeply $got, $exp, $desc;
+  }
+ }
+}
+
+{
+ is_imported 'Scope::Upper::Test::Mock10', '$', 0;
+ is_imported 'Scope::Upper::Test::Mock11', '$', \1;
+ is_imported 'Scope::Upper::Test::Mock12', '@', [ 2, 3 ];
+ is_imported 'Scope::Upper::Test::Mock13', '%', { a => 4 };
+ is_imported 'Scope::Upper::Test::Mock14', '&', sub { 5 };
+}
+
+# Invalid
+
+sub invalid_ref { qr/^Invalid \Q$_[0]\E reference as the localization target/ }
+
+{
+ eval { localize \1, 0 => HERE };
+ like $@, invalid_ref('SCALAR'), 'invalid localize \1, 0 => HERE';
+}
+
+{
+ eval { localize [ ], 0 => HERE };
+ like $@, invalid_ref('ARRAY'),  'invalid localize [ ], 0 => HERE';
+}
+
+{
+ eval { localize { }, 0 => HERE };
+ like $@, invalid_ref('HASH'),   'invalid localize { }, 0 => HERE';
+}
+
+{
+ eval { localize sub { }, 0 => HERE };
+ like $@, invalid_ref('CODE'),   'invalid localize sub { }, 0 => HERE';
+}