File Coverage

inc/Test/MockObject/Extends.pm
Criterion Covered Total %
statement 88 116 75.8
branch 8 22 36.3
condition n/a
subroutine 23 27 85.1
pod 10 10 100.0
total 129 175 73.7


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