File Coverage

inc/Test/MockObject/Extends.pm
Criterion Covered Total %
statement 100 120 83.3
branch 10 22 45.4
condition n/a
subroutine 26 28 92.8
pod 10 10 100.0
total 146 180 81.1


line stmt bran cond sub pod time code
1             #line 1
2             package Test::MockObject::Extends;
3             {
4             $Test::MockObject::Extends::VERSION = '1.20120301';
5             }
6 2     2   1892  
  2         4  
  2         81  
7 2     2   10 use strict;
  2         4  
  2         60  
8             use warnings;
9 2     2   2682  
  2         6914  
  2         13  
10             use Test::MockObject;
11              
12             sub import
13 2     2   17 {
14 2     2   11 my $self = shift;
  2         2  
  2         13  
  2         137  
15 2         30 eval "use Test::MockObject";
16             Test::MockObject->import( @_ );
17             }
18 2     2   4823  
  2         1306  
  2         11  
19 2     2   198 use Devel::Peek 'CvGV';
  2         10  
  2         797  
20             use Scalar::Util 'blessed';
21              
22             sub new
23 11     11 1 16383 {
24             my ($class, $fake_class) = @_;
25 11 50       73  
26             return Test::MockObject->new() unless defined $fake_class;
27 11         49  
28 11         55 my $parent_class = $class->get_class( $fake_class );
29 11 50       85 $class->check_class_loaded( $parent_class );
30             my $self = blessed( $fake_class ) ? $fake_class : {};
31 11         46  
32             bless $self, $class->gen_package( $parent_class );
33             }
34              
35             sub check_class_loaded
36 11     11 1 166 {
37 11         81 my ($self, $parent_class) = @_;
38             my $result = Test::MockObject->check_class_loaded(
39             $parent_class
40 11 50       166 );
41             return $result if $result;
42 0         0  
43 0         0 (my $load_class = $parent_class) =~ s/::/\//g;
44             require $load_class . '.pm';
45             }
46              
47             sub get_class
48 11     11 1 24 {
49             my ($self, $invocant) = @_;
50 11 50       67  
51 11         36 return $invocant unless blessed $invocant;
52             return ref $invocant;
53             }
54              
55             my $packname = 'a';
56              
57             sub gen_package
58 11     11 1 23 {
59 11         33 my ($class, $parent) = @_;
60             my $package = 'T::MO::E::' . $packname++;
61 2     2   13  
  2         4  
  2         384  
62 11         24 no strict 'refs';
  11         254  
63 11         29 *{ $package . '::mock' } = \&mock;
  11         61  
64 11         22 *{ $package . '::unmock' } = \&unmock;
  11         307  
65 11         47 @{ $package . '::ISA' } = ( $parent );
  11         59  
66 11         40 *{ $package . '::can' } = $class->gen_can( $parent );
  11         54  
67 11         44 *{ $package . '::isa' } = $class->gen_isa( $parent );
  11         58  
68 11         41 *{ $package . '::AUTOLOAD' } = $class->gen_autoload( $parent );
  11         60  
69             *{ $package . '::__get_parents' } = $class->gen_get_parents( $parent );
70 11         56  
71             return $package;
72             }
73              
74             sub gen_get_parents
75 11     11 1 29 {
76             my ($self, $parent) = @_;
77             return sub
78 2     2   11 {
  2         4  
  2         834  
79 0     0   0 no strict 'refs';
  0         0  
80 11         47 return @{ $parent . '::ISA' };
81             };
82             }
83              
84             sub gen_isa
85 11     11 1 20 {
86             my ($class, $parent) = @_;
87              
88             sub
89 1     1   8 {
90 1         3 local *__ANON__ = 'isa';
91 1 50       8 my ($self, $class) = @_;
92 0         0 return 1 if $class eq $parent;
93 0         0 my $isa = $parent->can( 'isa' );
94 11         59 return $isa->( $self, $class );
95             };
96             }
97              
98             sub gen_can
99 11     11 1 21 {
100             my ($class, $parent) = @_;
101              
102             sub
103 1     1   269 {
104 1         3 local *__ANON__ = 'can';
105 1         15 my ($self, $method) = @_;
106 1 50       6 my $parent_method = $self->SUPER::can( $method );
107 1         5 return $parent_method if $parent_method;
108 11         69 return Test::MockObject->can( $method );
109             };
110             }
111              
112             sub gen_autoload
113 11     11 1 22 {
114             my ($class, $parent) = @_;
115              
116             sub
117 62     62   397 {
118             our $AUTOLOAD;
119 62         168  
120 62 50       156 my $method = substr( $AUTOLOAD, rindex( $AUTOLOAD, ':' ) +1 );
121             return if $method eq 'DESTROY';
122 62         85  
123             my $self = shift;
124 62 50       1286  
    50          
    0          
125             if (my $parent_method = $parent->can( $method ))
126 0         0 {
127             return $self->$parent_method( @_ );
128             }
129             elsif (my $mock_method = Test::MockObject->can( $method ))
130 62         1404 {
131             return $self->$mock_method( @_ );
132             }
133             elsif (my $parent_al = $parent->can( 'AUTOLOAD' ))
134 0         0 {
135             my ($parent_pack) = CvGV( $parent_al ) =~ /\*(.*)::AUTOLOAD/;
136 2     2   12 {
  2         3  
  2         497  
  0         0  
137 0         0 no strict 'refs';
  0         0  
138             ${ "${parent_pack}::AUTOLOAD" } = "${parent}::${method}";
139 0         0 }
140 0         0 unshift @_, $self;
141             goto &$parent_al;
142             }
143             else
144 0         0 {
145             die "Undefined method $method at ", join( ' ', caller() ), "\n";
146 11         88 }
147             };
148             }
149              
150             sub mock
151 30     30 1 272 {
152             my ($self, $name, $sub) = @_;
153 30 50       126  
154             Test::MockObject::_set_log( $self, $name, ( $name =~ s/^-// ? 0 : 1 ) );
155              
156             my $mock_sub = sub
157 32     32   85 {
158 32         256 my ($self) = @_;
159 32         1173 $self->log_call( $name, @_ );
160 30         522 $sub->( @_ );
161             };
162              
163 2     2   11 {
  2         4  
  2         65  
  30         48  
164 2     2   10 no strict 'refs';
  2         3  
  2         196  
165 30         42 no warnings 'redefine';
  30         187  
166             *{ ref( $self ) . '::' . $name } = $mock_sub;
167             }
168 30         100  
169             return $self;
170             }
171              
172             sub unmock
173 0     0 1   {
174             my ($self, $name) = @_;
175 0            
176 2     2   8 Test::MockObject::_set_log( $self, $name, 0 );
  2         3  
  2         126  
177 0           no strict 'refs';
  0            
178 0           my $glob = *{ ref( $self ) . '::' };
179 0           delete $glob->{ $name };
180             return $self;
181             }
182              
183             1;
184             __END__