File Coverage

blib/lib/Test/Without/Module.pm
Criterion Covered Total %
statement 45 46 97.8
branch 7 8 87.5
condition n/a
subroutine 11 11 100.0
pod 1 5 20.0
total 64 70 91.4


line stmt bran cond sub pod time code
1             package Test::Without::Module;
2 6     6   318616 use strict;
  6         54  
  6         190  
3 6     6   40 use Carp qw( croak );
  6         13  
  6         323  
4              
5 6     6   35 use vars qw( $VERSION );
  6         12  
  6         399  
6             $VERSION = '0.21';
7              
8 6     6   42 use vars qw(%forbidden);
  6         31  
  6         3762  
9              
10             sub get_forbidden_list {
11 87     87 1 43003 \%forbidden
12             };
13              
14             sub import {
15 8     8   2036 my ($self,@forbidden_modules) = @_;
16              
17 8         29 my $forbidden = get_forbidden_list;
18            
19 8         31 for (@forbidden_modules) {
20 5         11 my $file = module2file($_);
21 5         27 $forbidden->{$file} = delete $INC{$file};
22             };
23              
24             # Scrub %INC, so that loaded modules disappear
25 8         21 for my $module (@forbidden_modules) {
26 5         14 scrub( $module );
27             };
28              
29 8 100       25 @INC = (\&fake_module, grep { !ref || $_ != \&fake_module } @INC);
  90         1807  
30             };
31              
32             sub fake_module {
33 75     75 0 508401 my ($self,$module_file,$member_only) = @_;
34             # Don't touch $@, or .al files will not load anymore????
35              
36 75 100       185 if (exists get_forbidden_list->{$module_file}) {
37 3         10 my $module_name = file2module($module_file);
38 3         606 croak "Can't locate $module_file in \@INC (you may need to install the $module_name module) (\@INC contains: @INC)";
39             };
40             };
41              
42             sub unimport {
43 2     2   17 my ($self,@list) = @_;
44 2         4 my $module;
45 2         4 my $forbidden = get_forbidden_list;
46              
47 2         5 for $module (@list) {
48 2         10 my $file = module2file($module);
49 2 50       8 if (exists $forbidden->{$file}) {
50 2         5 my $path = delete $forbidden->{$file};
51 2 100       1427 if (defined $path) {
52 1         1201 $INC{ $file } = $path;
53             }
54             } else {
55 0         0 croak "Can't allow non-forbidden module $module";
56             };
57             };
58             };
59              
60             sub file2module {
61 3     3 0 11 my ($mod) = @_;
62 3         12 $mod =~ s!/!::!g;
63 3         14 $mod =~ s!\.pm$!!;
64 3         37 $mod;
65             };
66              
67             sub module2file {
68 12     12 0 37 my ($mod) = @_;
69 12         103 $mod =~ s!::|'!/!g;
70 12         27 $mod .= ".pm";
71 12         46 $mod;
72             };
73              
74             sub scrub {
75 5     5 0 16 my ($module) = @_;
76 5         11 delete $INC{module2file($module)};
77             };
78              
79             1;
80              
81             =head1 NAME
82              
83             Test::Without::Module - Test fallback behaviour in absence of modules
84              
85             =head1 SYNOPSIS
86              
87             use Test::Without::Module qw( My::Module );
88              
89             # Now, loading of My::Module fails :
90             eval { require My::Module; };
91             warn $@ if $@;
92              
93             # Now it works again
94             eval q{ no Test::Without::Module qw( My::Module ) };
95             eval { require My::Module; };
96             print "Found My::Module" unless $@;
97              
98             =head1 DESCRIPTION
99              
100             This module allows you to deliberately hide modules from a program
101             even though they are installed. This is mostly useful for testing modules
102             that have a fallback when a certain dependency module is not installed.
103              
104             =head2 EXPORT
105              
106             None. All magic is done via C and
107             C.
108              
109             =head2 Test::Without::Module::get_forbidden_list
110              
111             This function returns a reference to a copy of the current hash of forbidden
112             modules or an empty hash if none are currently forbidden. This is convenient
113             if you are testing and/or debugging this module.
114              
115             =cut
116              
117             =head1 ONE LINER
118              
119             A neat trick for using this module from the command line
120             was mentioned to me by NUFFIN and by Jerrad Pierce:
121              
122             perl -MTest::Without::Module=Some::Module -w -Iblib/lib t/SomeModule.t
123              
124             That way, you can easily see how your module or test file behaves
125             when a certain module is unavailable.
126              
127             =head1 BUGS
128              
129             =over 4
130              
131             =item *
132              
133             There is no lexical scoping
134              
135             =back
136              
137             =head1 CREDITS
138              
139             Much improvement must be thanked to Aristotle from PerlMonks, he pointed me
140             to a much less convoluted way to fake a module at
141             L.
142              
143             I also discussed with him an even more elegant way of overriding
144             CORE::GLOBAL::require, but the parsing of the overridden subroutine
145             didn't work out the way I wanted it - CORE::require didn't recognize
146             barewords as such anymore.
147              
148             NUFFIN and Jerrad Pierce pointed out the convenient
149             use from the command line to interactively watch the
150             behaviour of the test suite and module in absence
151             of a module.
152              
153             =head1 AUTHOR
154              
155             Copyright (c) 2003-2014 Max Maischein, Ecorion@cpan.orgE
156              
157             =head1 LICENSE
158              
159             This module is released under the same terms as Perl itself.
160              
161             =head1 REPOSITORY
162              
163             The public repository of this module is
164             L.
165              
166             =head1 SUPPORT
167              
168             The public support forum of this module is
169             L.
170              
171             =head1 BUG TRACKER
172              
173             Please report bugs in this module via the RT CPAN bug queue at
174             L
175             or via mail to L.
176              
177             =head1 SEE ALSO
178              
179             L, L, L, L
180              
181             =cut
182              
183             __END__