--- /dev/null
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More tests => 3 + 7 * 2 + 8;
+
+use Scope::Upper qw<uplevel HERE UP>;
+
+sub depth {
+ my $depth = 0;
+ while (1) {
+ my @c = caller($depth);
+ last unless @c;
+ ++$depth;
+ }
+ return $depth - 1;
+}
+
+is depth(), 0, 'check top depth';
+is sub { depth() }->(), 1, 'check subroutine call depth';
+is do { local $@; eval { depth() } }, 1, 'check eval block depth';
+
+{
+ my $desc = 'uplevel in uplevel : lower frame';
+ local $@;
+ my @ret = eval {
+ 1, sub {
+ is depth(), 2, "$desc: correct depth 1";
+ 2, uplevel(sub {
+ is depth(), 2, "$desc: correct depth 2";
+ 3, sub {
+ is depth(), 3, "$desc: correct depth 3";
+ 4, uplevel(sub {
+ is depth(), 3, "$desc: correct depth 4";
+ return 5, @_;
+ }, 6, @_, HERE);
+ }->(7, @_);
+ }, 8, @_, HERE);
+ }->(9);
+ };
+ is $@, '', "$desc: no error";
+ is depth(), 0, "$desc: correct depth outside";
+ is_deeply \@ret, [ 1 .. 9 ], "$desc: correct return value"
+}
+
+{
+ my $desc = 'uplevel in uplevel : same frame';
+ local $@;
+ my @ret = eval {
+ 11, sub {
+ is depth(), 2, "$desc: correct depth 1";
+ 12, uplevel(sub {
+ is depth(), 2, "$desc: correct depth 2";
+ 13, sub {
+ is depth(), 3, "$desc: correct depth 3";
+ 14, uplevel(sub {
+ is depth(), 2, "$desc: correct depth 4";
+ return 15, @_;
+ }, 16, @_, UP);
+ }->(17, @_);
+ }, 18, @_, HERE);
+ }->(19);
+ };
+ is $@, '', "$desc: no error";
+ is depth(), 0, "$desc: correct depth outside";
+ is_deeply \@ret, [ 11 .. 19 ], "$desc: correct return value"
+}
+
+{
+ my $desc = 'uplevel in uplevel : higher frame';
+ local $@;
+ my @ret = eval {
+ 20, sub {
+ is depth(), 2, "$desc: correct depth 1";
+ 21, sub {
+ is depth(), 3, "$desc: correct depth 2";
+ 22, uplevel(sub {
+ is depth(), 3, "$desc: correct depth 3";
+ 23, sub {
+ is depth(), 4, "$desc: correct depth 4";
+ 24, uplevel(sub {
+ is depth(), 2, "$desc: correct depth 5";
+ return 25, @_;
+ }, 26, @_, UP UP);
+ }->(27, @_);
+ }, 28, @_, HERE);
+ }->(29, @_);
+ }->('2A');
+ };
+ is $@, '', "$desc: no error";
+ is depth(), 0, "$desc: correct depth outside";
+ is_deeply \@ret, [ 20 .. 29, '2A' ], "$desc: correct return value"
+}