use Test; plan 13; # L # L # Spec: # For any method name, there may be some number of candidate methods that could # handle the request: typically, inherited methods or multi variants. The # ordinary "dot" operator dispatches to a method in the standard fashion. There # are also "dot" variants that call some number of methods with the same name: # $object.?meth # calls method if there is one, otherwise undef class Parent { has Int $.cnt is rw; does plugin_1; does plugin_2; method meth {++$.cnt} } class Child is Parent { method meth {++$.cnt} method child_only {'child_only'} } role plugin_1 { multi method init_hook { $.cnt += 2 } } role plugin_2 { multi method init_hook { $.cnt += 3 } } { my $test = q"$object.?meth calls method if there is one"; my $object = Child.new; my $result = 1; # default to one to see if value changes to undef try { $result = $object.?nope }; ok($object.?meth, $test); is($result,undef, q" ..undef otherwise "); # TODO: add test for $object.?$meth (dynamic method) as well } { my $test = q"$object.*meth(@args) # calls all methods (0 or more)"; my $object = Child.new; my $result = 1; # default to one to see if value changes to undef try { $result = $object.*nope }; is($result,undef, q"$test: Case 0 returns undef"); try { $result = $object.*child_only }; is($result, 'child_only', "$test: Case 1 finds one result"); try { $result = $object.*meth }; is($object.cnt, 2, "$test: Case 2 visits both Child and Parent"); my $meth = 'meth'; $object = Child.new; try { $result = $object.*$meth }; is($object.cnt, 2, "$test: Case 2 visits both Child and Parent (as dynamic method call)"); my $meth = 'sqrt'; my $ans = 0; try { $ans = 4.*$meth }; is($ans, 2, q"$obj.*$meth works built-in methods like 'sqrt'"); } { # We should not only look in parent classes, but for matching # multi methods in parent classes! my $test = q"$object.*meth(@args) # calls all methods (0 or more) works on multi axis, too"; my $object = Child.new; my $got = 0; my $meth = 'init_hook'; try { $got = $object.*$meth }; is($got, 5, $test, :todo); } { my $test = q"$object.+meth(@args) # calls all methods (1 or more)"; my $object = Child.new; my $result = 1; # default to one to see if value changes to undef try { $result = $object.+nope }; ok($!, q"$test: Case 0 dies"); try { $result = $object.+child_only }; is($result, 'child_only', "$test: Case 1 fines one result"); try { $result = $object.+meth }; is($object.cnt, 2, "$test: Case 2 visits both Child and Parent"); # TODO: add test for $object.+$meth (dynamic method) as well } ok(0,q'STUB: $object.*WALK[:breadth:omit($?CLASS)]::meth(@args);', :todo ); ok(0, "STUB: there is more Calling Sets functionality which needs tests", :todo); # vim: ft=perl6