File Coverage

blib/lib/Module/Stubber.pm
Criterion Covered Total %
statement 77 83 92.7
branch 14 22 63.6
condition 3 6 50.0
subroutine 14 14 100.0
pod n/a
total 108 125 86.4


line stmt bran cond sub pod time code
1             package Module::Stubber::Stub;
2 1     1   37952 use strict;
  1         3  
  1         34  
3 1     1   6 use warnings;
  1         1  
  1         29  
4 1     1   4 use base qw(Exporter);
  1         6  
  1         534  
5              
6             our $AUTOLOAD;
7             our %Retvals;
8             our @EXPORT;
9              
10             our $MSG_FMT = <
11             *** '%s' requested at %s:%d
12             *** This symbol does not really exist, and has been
13             *** implemented as a stub by Module::Stubber.
14             *** Depending on how important
15             *** this function is, this program may not function
16             *** correctly. This message will only display once.
17             EOS
18              
19             our %Warncache;
20             sub _can_warn($) {
21 3     3   6 my $key = shift;
22 3         21 (my $cls = $key) =~ s/::[^:]+$//g;
23 3   33     20 return !(exists $Warncache{$cls} || exists $Warncache{$key});
24             }
25              
26             sub AUTOLOAD {
27 2     2   400 my $arg = shift;
28 2         29 my $fn = $AUTOLOAD;
29 2         22 my @callinfo = caller(0);
30 2         8 my ($pkg,$fname,$line,$subname) = @callinfo[0..3];
31 2 50       6 if(_can_warn($fn)) {
32 0         0 printf STDERR ($MSG_FMT, $fn, $fname, $line);
33 0         0 $Warncache{$fn} = 1;
34             }
35            
36 2 50       40 if(!exists $Retvals{$fn}) {
37 2 100       11 return $arg if ref $arg;
38 1         5 return 1;
39             }
40            
41 0         0 return $Retvals{$fn};
42             }
43              
44             sub new {
45 1     1   2543 my $cls = shift;
46 1         2 my $s = "Dummy Object";
47 1         4 my ($pkg,$file,$line) = caller();
48 1 50       4 printf STDERR $MSG_FMT, $cls . "::new", $file, $line if _can_warn($cls . "::new");
49 1         4 bless \$s, $cls;
50             }
51              
52             sub import {
53 4     4   269 my ($cls,@options) = @_;
54 4 50       12 my @esyms = grep { !ref $_ && $_ =~ m/^[a-zA-Z_\$\@\%\&]/ } @options;
  13         111  
55 1     1   5 no strict 'refs';
  1         1  
  1         86  
56            
57 4         9 @{$cls.'::EXPORT'} = @esyms;
  4         32  
58 4         11 *{$cls.'::AUTOLOAD'} = \&AUTOLOAD;
  4         21  
59 4         15 @_ = ($cls,@esyms);
60 4         1690 goto &Exporter::import;
61             }
62              
63             package Module::Stubber;
64 1     1   4 use strict;
  1         1  
  1         20  
65 1     1   4 use warnings;
  1         1  
  1         220  
66             our %Status;
67             our $VERSION = '0.03';
68              
69             my $USAGE_ERR = sprintf("Usage: use %s ".
70             "Pkg::Name => [ 'import', 'options' ], extra => 'options'",
71             __PACKAGE__);
72              
73             sub import {
74 4     4   984 my ($cls,$wanted_pkg,$import_params,%options) = @_;
75 4         21 my ($caller,$ifname,$ifline) = caller();
76 4 50       15 if(!$wanted_pkg) {
77 0         0 die $USAGE_ERR;
78             }
79            
80 4         8 my $pkg_s = $wanted_pkg;
81 4         12 $pkg_s =~ s,::,/,g;
82 4         6 $pkg_s .= ".pm";
83            
84 4         20 @_ = ($wanted_pkg, @$import_params);
85 4 100 66     7 if(eval { require $pkg_s }
  4         9839  
86             && !$wanted_pkg->isa('Module::Stubber::Stub') ) {
87 2         414 $Status{$wanted_pkg} = 1;
88 2 100   1   7 goto &{$wanted_pkg->can('import') || sub () { } };
  2         95  
  1         13  
89             } else {
90 2         1012 warn(__PACKAGE__ . ": ".$@);
91 2         14 $Status{$wanted_pkg} = 0;
92 2         7 $INC{$pkg_s} = 1;
93 1     1   4 no strict 'refs';
  1         9  
  1         50  
94 2         4 @{$wanted_pkg . '::ISA'} = 'Module::Stubber::Stub';
  2         70  
95 2         5 my $more_syms = $options{will_use};
96 2 50       9 if(ref $more_syms eq 'ARRAY') {
97 0         0 push @_, @$more_syms;
98             } else {
99 1     1   4 no strict 'refs';
  1         2  
  1         179  
100 2         25 while (my ($sym,$symspec) = each %$more_syms) {
101 10 50       23 if(ref $symspec eq 'CODE') {
102 10         13 *{$wanted_pkg."::$sym"} = $symspec;
  10         51  
103             } else {
104 0         0 $Module::Stubber::Stub::Retvals{$wanted_pkg."::$sym"} = $symspec;
105             }
106 10         45 push @_, $sym;
107             }
108             }
109 2 50       8 if($options{silent}) {
110 2         5 $Module::Stubber::Stub::Warncache{$wanted_pkg} = 1;
111             }
112            
113 2         5419 goto &Module::Stubber::Stub::import;
114             }
115             }
116              
117             1;
118              
119             __END__