File: | blib/lib/Test/Mocha/SpyBase.pm |
Coverage: | 98.5% |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Test::Mocha::SpyBase; | ||||||
2 | # ABSTRACT: Abstract base class for Spy and Mock | ||||||
3 | $Test::Mocha::SpyBase::VERSION = '0.61'; | ||||||
4 | 12 12 12 | 3985 10 209 | use strict; | ||||
5 | 12 12 12 | 24 20 170 | use warnings; | ||||
6 | |||||||
7 | 12 12 12 | 23 155 353 | use Carp 1.22 'croak'; | ||||
8 | 12 12 12 | 3797 289814 67 | use Types::Standard qw( ArrayRef HashRef ); | ||||
9 | |||||||
10 | # class attributes | ||||||
11 | our $CaptureMode = 0; | ||||||
12 | my $NumMethodCalls = 0; | ||||||
13 | my $LastMethodCall; | ||||||
14 | |||||||
15 | ## no critic (NamingConventions::Capitalization) | ||||||
16 | sub __CaptureMode { | ||||||
17 | 273 | 178 | my ( $class, $value ) = @_; | ||||
18 | 273 | 399 | return $CaptureMode; | ||||
19 | } | ||||||
20 | |||||||
21 | sub __NumMethodCalls { | ||||||
22 | 262 | 146 | my ( $class, $value ) = @_; | ||||
23 | |||||||
24 | 262 | 250 | if ( defined $value ) { | ||||
25 | 131 | 86 | $NumMethodCalls = $value; | ||||
26 | } | ||||||
27 | 262 | 280 | return $NumMethodCalls; | ||||
28 | } | ||||||
29 | |||||||
30 | sub __LastMethodCall { | ||||||
31 | 131 | 79 | my ( $class, $value ) = @_; | ||||
32 | |||||||
33 | 131 | 130 | if ( defined $value ) { | ||||
34 | 131 | 74 | $LastMethodCall = $value; | ||||
35 | } | ||||||
36 | 131 | 109 | return $LastMethodCall; | ||||
37 | } | ||||||
38 | ## use critic | ||||||
39 | |||||||
40 | sub __new { | ||||||
41 | 34 | 81 | my %args = ( | ||||
42 | calls => [], # ArrayRef[ MethodCall ] | ||||||
43 | stubs => {}, # $method_name => ArrayRef[ MethodStub ] | ||||||
44 | ); | ||||||
45 | 34 | 55 | return \%args; | ||||
46 | } | ||||||
47 | |||||||
48 | sub __calls { | ||||||
49 | 244 | 353 | my ($self) = @_; | ||||
50 | 244 | 350 | return $self->{calls}; | ||||
51 | } | ||||||
52 | |||||||
53 | sub __stubs { | ||||||
54 | 183 | 99 | my ($self) = @_; | ||||
55 | 183 | 203 | return $self->{stubs}; | ||||
56 | } | ||||||
57 | |||||||
58 | sub __find_stub { | ||||||
59 | # """ | ||||||
60 | # Returns the first stub that satisfies the given method call. | ||||||
61 | # Returns undef if no stub is found. | ||||||
62 | # """ | ||||||
63 | 141 | 87 | my ( $self, $method_call ) = @_; | ||||
64 | 141 | 149 | my $stubs = $self->__stubs; | ||||
65 | |||||||
66 | 141 | 214 | return if !defined $stubs->{ $method_call->name }; | ||||
67 | |||||||
68 | 62 62 | 43 89 | foreach my $stub ( @{ $stubs->{ $method_call->name } } ) { | ||||
69 | 68 | 125 | return $stub if $stub->__satisfied_by($method_call); | ||||
70 | } | ||||||
71 | 3 | 5 | return; | ||||
72 | } | ||||||
73 | |||||||
74 | sub __capture_method_call { | ||||||
75 | # """ | ||||||
76 | # Get the last method called on a mock object, | ||||||
77 | # removes it from the invocation history, | ||||||
78 | # and restores the last method stub response. | ||||||
79 | # """ | ||||||
80 | 140 | 108 | my ( $class, $coderef ) = @_; | ||||
81 | |||||||
82 | ### assert: !$CaptureMode | ||||||
83 | 140 | 98 | $NumMethodCalls = 0; | ||||
84 | 140 | 109 | $LastMethodCall = undef; | ||||
85 | { | ||||||
86 | # Execute the coderef. This should in turn include a method call on | ||||||
87 | # mock, which should be handled by its AUTOLOAD method. | ||||||
88 | 140 140 | 362 278 | local $CaptureMode = 1; | ||||
89 | 140 | 170 | $coderef->(); | ||||
90 | } | ||||||
91 | |||||||
92 | 131 | 256 | croak 'Coderef must have a method invoked on a mock object' | ||||
93 | if $NumMethodCalls == 0; | ||||||
94 | 130 | 214 | croak 'Coderef must not have multiple methods invoked on a mock object' | ||||
95 | if $NumMethodCalls > 1; | ||||||
96 | |||||||
97 | 129 | 169 | return $LastMethodCall; | ||||
98 | } | ||||||
99 | |||||||
100 | 1; |