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   40 use strict;
  8         11  
  8         269  
3 8     8   40 use warnings;
  8         19  
  8         277  
4              
5 8     8   42 use base 'Exporter';
  8         44  
  8         902  
6 8     8   47 use Scalar::Util qw/blessed/;
  8         49  
  8         828  
7 8     8   1997 use Mock::Quick::Method;
  8         14  
  8         354  
8 8     8   40 use Carp qw/croak/;
  8         20  
  8         999  
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 217 my ( $package, $name, $code ) = @_;
24 8     8   46 no warnings 'redefine';
  8         22  
  8         442  
25 8     8   99 no strict 'refs';
  8         12  
  8         6861  
26 103         107 *{"$package\::$name"} = $code;
  103         710  
27             }
28              
29             sub call {
30 65     65 0 684 my $self = shift;
31 65         314 require Mock::Quick::Object::Control;
32 65         206 my $control = Mock::Quick::Object::Control->new( $self );
33 65         70 my $name = shift;
34              
35 65         150 my $class = blessed( $self );
36 65 50       128 croak "Can't call method on an unblessed reference"
37             unless $class;
38              
39 65 100       135 if ( $control->strict ) {
40             croak "Can't locate object method \"$name\" in this instance"
41 8 100       38 unless exists $self->{$name};
42             }
43              
44 64 100 100     225 if ( @_ && ref $_[0] && "$_[0]" eq "" . \$CLEAR ) {
      100        
45 7         53 delete $self->{ $name };
46 7         20 delete $control->metrics->{$name};
47 7         23 return;
48             }
49              
50 57         125 $control->metrics->{$name}++;
51              
52             return $self->{ $name }->( $self, @_ )
53             if exists( $self->{ $name })
54             && blessed( $self->{ $name })
55 57 100 100     383 && blessed( $self->{ $name })->isa( 'Mock::Quick::Method' );
      66        
56              
57 39 100 66     150 return $self->{$name} = shift(@_)
58             if blessed( $_[0] ) && blessed( $_[0] )->isa( 'Mock::Quick::Method' );
59              
60 38         85 param( $self, $name, @_ );
61             }
62              
63             sub param {
64 38     38 0 36 my $self = shift;
65 38         38 my $name = shift;
66              
67 38 100       71 $self->{$name} = shift(@_) if @_;
68              
69             # Prevent autovivication
70 38 100       202 return unless exists( $self->{ $name });
71 18         123 return $self->{ $name };
72             }
73              
74             sub class_meth {
75 8     8 0 494 my ( $name, $block ) = @_;
76 8         26 my $caller = caller;
77              
78             my $sub = sub {
79 13 50   13   233 goto &$block unless blessed( $_[0] );
80 0         0 unshift @_ => ( shift(@_), $name );
81 0         0 goto &call;
82 8         141 };
83              
84 8         28 inject( $caller, $name, $sub );
85             }
86              
87             sub obj_meth {
88 8     8 0 433 my ( $name, $block ) = @_;
89 8         25 my $caller = caller;
90              
91             my $sub = sub {
92 15 100   15   3719 goto &$block if blessed( $_[0] );
93 1         28 Carp::croak( "Can't locate object method \"$name\" via package \"$caller\"" );
94 8         117 };
95              
96 8         21 inject( $caller, $name, $sub );
97             }
98              
99             sub alt_meth {
100 12     12 0 82 my ( $name, %alts ) = @_;
101 12         45 my $caller = caller;
102              
103             croak "You must provide an action for both 'class' and 'obj'"
104 12 50 33     255 unless $alts{class} && $alts{obj};
105              
106             my $sub = sub {
107 32 100   32   3388 goto &{ $alts{obj }} if blessed( $_[0] );
  20         75  
108 12         17 goto &{ $alts{ class }};
  12         64  
109 12         51 };
110              
111 12         168 inject( $caller, $name, $sub );
112             }
113              
114             sub purge_util {
115 22     22 0 1027 my $caller = caller;
116 22         319 for my $sub ( @EXPORT ) {
117 8     8   52 no strict 'refs';
  8         11  
  8         756  
118 176         137 my $ref = \%{"$caller\::"};
  176         306  
119 176         395 delete $ref->{ $sub };
120             }
121             }
122              
123             1;
124              
125             __END__