File Coverage

blib/lib/Mock/Quick/Util.pm
Criterion Covered Total %
statement 76 78 97.4
branch 21 24 87.5
condition 14 18 77.7
subroutine 19 19 100.0
pod 0 7 0.0
total 130 146 89.0


line stmt bran cond sub pod time code
1             package Mock::Quick::Util;
2 8     8   25 use strict;
  8         9  
  8         164  
3 8     8   21 use warnings;
  8         13  
  8         151  
4              
5 8     8   21 use base 'Exporter';
  8         31  
  8         493  
6 8     8   32 use Scalar::Util qw/blessed/;
  8         28  
  8         462  
7 8     8   1218 use Mock::Quick::Method;
  8         8  
  8         146  
8 8     8   23 use Carp qw/croak/;
  8         7  
  8         591  
9              
10             our $CLEAR = 'clear';
11             our @EXPORT = qw/
12             class_meth
13             obj_meth
14             alt_meth
15             call
16             param
17             inject
18             purge_util
19             super
20             /;
21              
22             sub inject {
23 103     103 0 289 my ( $package, $name, $code ) = @_;
24 8     8   27 no warnings 'redefine';
  8         15  
  8         220  
25 8     8   23 no strict 'refs';
  8         5  
  8         4165  
26 103         86 *{"$package\::$name"} = $code;
  103         516  
27             }
28              
29             sub call {
30 65     65 0 795 my $self = shift;
31 65         241 require Mock::Quick::Object::Control;
32 65         130 my $control = Mock::Quick::Object::Control->new( $self );
33 65         57 my $name = shift;
34              
35 65         122 my $class = blessed( $self );
36 65 50       105 croak "Can't call method on an unblessed reference"
37             unless $class;
38              
39 65 100       102 if ( $control->strict ) {
40             croak "Can't locate object method \"$name\" in this instance"
41 8 100       23 unless exists $self->{$name};
42             }
43              
44 64 100 100     189 if ( @_ && ref $_[0] && "$_[0]" eq "" . \$CLEAR ) {
      100        
45 7         62 delete $self->{ $name };
46 7         19 delete $control->metrics->{$name};
47 7         23 return;
48             }
49              
50 57         99 $control->metrics->{$name}++;
51              
52             return $self->{ $name }->( $self, @_ )
53             if exists( $self->{ $name })
54             && blessed( $self->{ $name })
55 57 100 100     295 && blessed( $self->{ $name })->isa( 'Mock::Quick::Method' );
      66        
56              
57 39 100 66     144 return $self->{$name} = shift(@_)
58             if blessed( $_[0] ) && blessed( $_[0] )->isa( 'Mock::Quick::Method' );
59              
60 38         82 param( $self, $name, @_ );
61             }
62              
63             sub param {
64 38     38 0 28 my $self = shift;
65 38         33 my $name = shift;
66              
67 38 100       56 $self->{$name} = shift(@_) if @_;
68              
69             # Prevent autovivication
70 38 100       162 return unless exists( $self->{ $name });
71 18         92 return $self->{ $name };
72             }
73              
74             sub class_meth {
75 8     8 0 34 my ( $name, $block ) = @_;
76 8         18 my $caller = caller;
77              
78             my $sub = sub {
79 13 50   13   186 goto &$block unless blessed( $_[0] );
80 0         0 unshift @_ => ( shift(@_), $name );
81 0         0 goto &call;
82 8         100 };
83              
84 8         17 inject( $caller, $name, $sub );
85             }
86              
87             sub obj_meth {
88 8     8 0 27 my ( $name, $block ) = @_;
89 8         15 my $caller = caller;
90              
91             my $sub = sub {
92 15 100   15   3288 goto &$block if blessed( $_[0] );
93 1         21 Carp::croak( "Can't locate object method \"$name\" via package \"$caller\"" );
94 8         74 };
95              
96 8         13 inject( $caller, $name, $sub );
97             }
98              
99             sub alt_meth {
100 12     12 0 1025 my ( $name, %alts ) = @_;
101 12         24 my $caller = caller;
102              
103             croak "You must provide an action for both 'class' and 'obj'"
104 12 50 33     166 unless $alts{class} && $alts{obj};
105              
106             my $sub = sub {
107 32 100   32   2087 goto &{ $alts{obj }} if blessed( $_[0] );
  20         61  
108 12         12 goto &{ $alts{ class }};
  12         42  
109 12         27 };
110              
111 12         22 inject( $caller, $name, $sub );
112             }
113              
114             sub purge_util {
115 22     22 0 491 my $caller = caller;
116 22         217 for my $sub ( @EXPORT ) {
117 8     8   31 no strict 'refs';
  8         6  
  8         458  
118 176         118 my $ref = \%{"$caller\::"};
  176         206  
119 176         244 delete $ref->{ $sub };
120             }
121             }
122              
123             1;
124              
125             __END__