25 / 25 lines covered (100.0%)
1unit module BDD::Behave::Mock::Spy;23use BDD::Behave::Mock::Double;4use BDD::Behave::Mock::Stub;56constant SPY-RESERVED-METHODS = set <7 BUILD BUILDALL DESTROY new clone perl raku gist Str8 defined DEFINITE WHAT WHO HOW WHICH WHERE so not Bool9 ACCEPTS dispatch:<.> dispatch:<.?> dispatch:<.+> dispatch:<.*>10>;1112sub spy-method-candidates(Mu \cls) {13 my @names;14 my %seen;15 for cls.^methods(:local) -> $m {16 next unless $m ~~ Method;17 next if $m ~~ Submethod;18 my $name = try { $m.name };19 next unless $name.defined && $name ~~ Str;20 next if $name eq '' || $name.starts-with('!');21 next if $name (elem) SPY-RESERVED-METHODS;22 next if %seen{$name}++;23 @names.push($name);24 }25 @names;26}2728our sub spy(|args) is export {29 my @pos = args.list;30 my %named = args.hash;3132 if @pos.elems == 0 && %named.elems == 0 {33 return Double.new(:double-name<spy>);34 }3536 if @pos.elems == 1 && %named.elems == 0 {37 my \arg = @pos[0];38 if arg.defined && arg.DEFINITE && arg !~~ Str {39 my $cls = arg.WHAT;40 for spy-method-candidates($cls) -> $name {41 my $stub = Stub.new(:target(arg), :method-name($name));42 $stub.install;43 StubRegistry.register($stub);44 $stub.and-call-original;45 }46 return arg;47 }48 }4950 double(|args);51}