use v6-alpha;
use Test;
# various tests derived from L<S10/Autoloading>
plan 38;
if $?PUGS_BACKEND ne "BACKEND_PUGS" {
skip_rest "PIL2JS and PIL-Run do not support eval() yet.";
exit;
}
package OughtaLoad {
sub AUTOLOAD(*@args) {
"\&{$_}({ @args.map:{"'$_'"}.join(", ") })"
};
}
# currently, $_ is passed in as a global as per spec!
$_ = "test";
my $x = OughtaLoad::AUTOLOAD(1,2,3);
is($x, q[&test('1', '2', '3')], "sanity");
lives_ok { $x = OughtaLoad::test(2,3,4) },
"AUTOLOAD", :todo<feature>;
package OughtaWork {
our $s = 0;
sub AUTOSCALAR($_) { my $v = "\$$_ number {++$s}";
eval "our \$$_ := \$v";
\$v }
our $a = 0;
sub AUTOARRAY($_) { my @v = ( "auto", $_, ++$a );
eval "our @$_ := @v";
\@v }
our $h = 0;
sub AUTOHASH($_) { my %v = ( auto => $_, num => ++$h );
eval "our %$_ := %v";
\%v }
our $u = 0;
sub AUTOSUB($_) { my $x = "\&{$_} number {++$u}";
my $sub = sub { $x };
eval "our &$_ := \$sub";
return $sub;
}
our $m = 0;
method AUTOMETH($_) { my $x = "{self} {$_}.number {++$m}";
my $method = sub($self:) { "{$self}.$x" };
eval "our &$_ := \$method";
return $method;
}
}
# however, the use of $_ in the above is because the first argument is
# bound to $_ via "default invocants" (which seems to not be
# working... hmm)
$_ = "poison";
# scalar
$x = OughtaWork::AUTOSCALAR("test");
is($x, q[$test number 1], "AUTOSCALAR sanity test");
lives_ok { $x = $OughtaWork::foo }, "AUTOSCALAR - first";
is($x, q[$foo number 2], "Returns correct var", :todo<feature>);
$x="";
lives_ok { $x = $OughtaWork::foo }, "AUTOSCALAR - repeat";
is($x, q[$foo number 2], "AUTOSCALAR only called once", :todo<feature>);
lives_ok { $x = $OughtaWork::bar }, "AUTOSCALAR - second";
is($x, q[$bar number 3], "Returns correct var", :todo<feature>);
# array
my $a = OughtaWork::AUTOARRAY("test");
is($a.join(","), q[auto,test,1], "AUTOARRAY sanity test");
my @a;
lives_ok { @a = @OughtaWork::foo }, "AUTOARRAY - first";
is(@a.join(","), q[auto,foo,2], "Returns correct var", :todo<feature>);
@a=();
lives_ok { @a = @OughtaWork::foo }, "AUTOARRAY - repeat";
is(@a.join(","), q[auto,foo,2], "AUTOARRAY only called once", :todo<feature>);
lives_ok { @a = @OughtaWork::bar }, "AUTOARRAY - second";
is(@a.join(","), q[auto,bar,3], "Returns correct var", :todo<feature>);
# hash
my %h = OughtaWork::AUTOHASH("test");
is(%h.kv.sort.join(","), q[1,auto,num,test], "AUTOHASH sanity test");
lives_ok { %h = %OughtaWork::foo }, "AUTOHASH - first";
is(%h.kv.sort.join(","), q[2,auto,foo,num], "Returns correct var", :todo<feature>);
%h=();
lives_ok { %h = %OughtaWork::foo }, "AUTOHASH - repeat";
is(%h.kv.sort.join(","), q[2,auto,foo,num], "AUTOHASH only called once", :todo<feature>);
lives_ok { %h = %OughtaWork::bar }, "AUTOHASH - second";
is(%h.kv.sort.join(","), q[3,auto,bar,num], "Returns correct var", :todo<feature>);
# sub
my $s = OughtaWork::AUTOSUB("test");
my $v = $s();
is($v, q[&test number 1], "AUTOSUB sanity test");
$v="";
ok eval(q{ $s = &OughtaWork::foo; $v = $s(); }),
"AUTOSUB - first", :todo<feature>;
is($v, q[&foo number 2], "Returns correct var", :todo<feature>);
$v="";
ok eval(q{ $s = &OughtaWork::foo; $v = $s(); }),
"AUTOSUB - repeat", :todo<feature>;
is($v, q[&foo number 2], "AUTOSUB only called once", :todo<feature>);
$v="";
ok eval(q{ $s = &OughtaWork::bar; $v = $s(); }),
"AUTOSUB - second", :todo<feature>;
is($v, q[&bar number 3], "Returns correct var", :todo<feature>);
# presumably AUTOMETH on packages only has any meaning to "package
# methods"; they have to be classes or roles for AUTOMETH to be method
# lookups.
my $inv = ::OughtaWork;
ok eval(q{ $s = OughtaWork.AUTOMETH("test"); $v = $s($inv:) }),
"AUTOMETH - sanity", :todo<bug>;
is($v, q[OughtaWork.test number 1], "AUTOMETH sanity test", :todo<bug>);
$v = "";
ok eval(q{ $s = OughtaWork.foo; $v = $s($inv:) }),
"AUTOMETH - first", :todo<feature>;
is($x, q[OughtaWork.foo number 2], "Returns correct var", :todo<feature>);
$s = sub { };
ok eval(q{ $s = OughtaWork.foo; $v = $s($inv:) }),
"AUTOMETH - repeat", :todo<feature>;
is($x, q[OughtaWork.foo number 2], "AUTOMETH only called once", :todo<feature>);
ok eval(q{ $s = OughtaWork.bar; $v = $s($inv:) }),
"AUTOMETH - second", :todo<feature>;
is($x, q[OughtaWork.bar number 3], "Returns correct var", :todo<feature>);
# discovered bugs (TODO: write tests to track down:)
# 1. changing the is($v, ...) to is($s(), ...) causes:
# pugs: cannot cast from VInt 1 to Pugs.AST.Internals.VCode
# seems to work interactively though;
# pugs> package OughtaWork { our $u = 0; sub AUTOSUB { my $x = "\&{$_} number {++$u}"; sub { $x } } }
# undef
# pugs> my $s = OughtaWork::AUTOSUB
# sub {...}
# pugs> $s
# sub {...}
# pugs> $s()
# '& number 1'
# further investigation required...
# 2. named subs don't seem to get implicit arguments via $_ (actually
# as per S04 this seems to be design behaviour)
# 3. Various nonsense with using a Package as an invocant in a method
# call
# 4. Couldn't take ref of a method via &Package.foo