Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
roast/S06-routine-modifiers/proxy.t
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
137 lines (110 sloc)
4.25 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use v6; | |
use Test; | |
# Tests for the Proxy class | |
# L<S06/Lvalue subroutines/"or a specially tied proxy object, with suitably"> | |
# Return value of assignments of Proxy objects is decided now. | |
# See thread "Assigning Proxy objects" on p6l, | |
# L<"http://www.nntp.perl.org/group/perl.perl6.language/21838">. | |
# Quoting Larry: | |
# The intention is that lvalue subs behave in all respects as if they | |
# were variables. So consider what | |
# | |
# say $nonproxy = 40; | |
# | |
# should do. | |
plan 26; | |
my $foo = 42; | |
my $was_inside = 0; | |
sub lvalue_test1() is rw { | |
$was_inside++; | |
return-rw Proxy.new: | |
FETCH => method () { 100 + $foo }, | |
STORE => method ($new) { $foo = $new - 100 }; | |
}; | |
{ | |
is $foo, 42, "basic sanity (1)"; | |
is $was_inside, 0, "basic sanity (2)"; | |
is lvalue_test1(), 142, "getting var through Proxy (1)"; | |
# No todo_is here to avoid unexpected succeeds (? - elaborate?) | |
is $was_inside, 1, "lvalue_test1() was called (1)"; | |
is (lvalue_test1() = 123), 123, "setting var through Proxy"; | |
is $was_inside, 2, "lvalue_test1() was called (2)"; | |
is $foo, 23, "var was correctly set (1)"; | |
is lvalue_test1(), 123, "getting var through Proxy (2)"; | |
is $was_inside, 3, "lvalue_test1() was called (3)"; | |
} | |
$foo = 4; | |
$was_inside = 0; | |
sub lvalue_test2() is rw { | |
$was_inside++; | |
return-rw Proxy.new: | |
FETCH => method () { 10 + $foo }, | |
STORE => method ($new) { $foo = $new - 100 }; | |
}; | |
{ | |
is $foo, 4, "basic sanity (3)"; | |
is $was_inside, 0, "basic sanity (4)"; | |
is lvalue_test2(), 14, "getting var through Proxy (4)"; | |
# No todo_is here to avoid unexpected succeeds | |
is $was_inside, 1, "lvalue_test2() was called (4)"; | |
is (lvalue_test2() = 106), 16, "setting var through Proxy returns new value of the var"; | |
is $was_inside, 2, "lvalue_test2() was called (5)"; | |
is $foo, 6, "var was correctly set (2)"; | |
is lvalue_test2(), 16, "getting var through Proxy (5)"; | |
is $was_inside, 3, "lvalue_test2() was called (5)"; | |
} | |
$foo = 4; | |
$was_inside = 0; | |
sub lvalue_test3() { | |
$was_inside++; | |
return Proxy.new: | |
FETCH => method () { 10 + $foo }, | |
STORE => method ($new) { $was_inside = 42 }; | |
}; | |
{ | |
is $foo, 4, "basic sanity (6)"; | |
is $was_inside, 0, "basic sanity (7)"; | |
is lvalue_test3(), 14, "getting var through Proxy (8)"; | |
# No todo_is here to avoid unexpected succeeds | |
is $was_inside, 1, "lvalue_test3() was called (8)"; | |
dies-ok { EVAL '(lvalue_test3() = 42)' }, "Proxy returned from non is-rw is prefetched rvalue"; | |
is $was_inside, 2, "lvalue_test3() was called (9)"; | |
} | |
# https://github.com/rakudo/rakudo/issues/1466 | |
subtest '.raku on Proxied object does not crash' => { | |
plan 4; | |
eval-lives-ok 「(Proxy.new: :STORE{$^a,$^b}, :FETCH{Int}).VAR.raku」, | |
'Int fetch value'; | |
eval-lives-ok 「(Proxy.new: :STORE{$^a,$^b}, :FETCH{Nil}).VAR.raku」, | |
'Nil fetch value'; | |
eval-lives-ok 「(Proxy.new: :STORE{$^a,$^b}, :FETCH{IterationEnd}).VAR.raku」, | |
'IterationEnd fetch value'; | |
eval-lives-ok 「(Proxy.new: :STORE{$^a,$^b}, :FETCH{42}).VAR.raku」, | |
'42 (i.e. .DEFINITE) fetch value'; | |
} | |
# subclassing a Proxy | |
subtest 'creating and using a subclass of Proxy' => { | |
plan 7; | |
sub historize($value is copy) is raw { | |
class History is Proxy { has @.history } | |
my $proxy := History.new( | |
FETCH => -> $ { $value }, | |
STORE => -> $, \new-value { | |
$proxy.VAR.history.push($value); | |
$value = new-value | |
} | |
) | |
} | |
my $a := historize(42); | |
is $a, 42, 'did the value arrive'; | |
is-deeply $a.VAR.history, [], 'still no history'; | |
$a = 666; | |
is $a, 666, 'did the change arrive'; | |
is-deeply $a.VAR.history, [42], 'check we see the previous value'; | |
$a++; | |
is $a, 667, 'did the increment arrive'; | |
is-deeply $a.VAR.history, [42,666], 'check we see the previous values'; | |
$a.VAR.history = (); | |
is-deeply $a.VAR.history, [], 'did the reset work'; | |
} | |
# vim: expandtab shiftwidth=4 |