File Coverage

lib/Test/NoBreakpoints.pm
Criterion Covered Total %
statement 60 65 92.3
branch 24 34 70.5
condition 3 6 50.0
subroutine 9 10 90.0
pod 3 3 100.0
total 99 118 83.9


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Test::NoBreakpoints - test that files do not contain soft breakpoints
4              
5             =head1 SYNOPSIS
6              
7             use Test::NoBreakpoints;
8             plan tests => $num_tests;
9             no_breakpoints_ok( $file, 'Contains no soft breakpoints' );
10              
11             Module authors can include the following in a t/nobreakpoints.t file to add
12             such checking to a module distribution:
13              
14             use Test::More;
15             eval "use Test::NoBreakpoints 0.10";
16             plan skip_all => "Test::NoBreakpoints 0.10 required for testing" if $@;
17             all_files_no_breakpoints_ok();
18              
19             =head1 DESCRIPTION
20              
21             I love soft breakpoints (C<$DB::single = 1>) in the Perl debugger.
22             Unfortunately, I have a habit of putting them in my code during development
23             and forgetting to take them out before I upload it to CPAN, necessitating a
24             hasty fix/package/bundle cycle followed by much cursing.
25              
26             Test::NoBreakpoints checks that files contain neither the string
27             C<$DB::single = 1> nor C<$DB::signal = 1>. By adding such a test to all my
28             modules, I swear less and presumably lighten the load on the CPAN in some
29             small way.
30              
31             =cut
32              
33             package Test::NoBreakpoints;
34              
35 5     5   259055 use strict;
  5         45  
  5         151  
36              
37 5     5   25 use File::Spec;
  5         6  
  5         86  
38 5     5   27 use File::Find;
  5         8  
  5         288  
39 5     5   25 use Test::Builder;
  5         7  
  5         162  
40              
41             require Exporter;
42 5     5   30 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  5         8  
  5         3784  
43              
44             $VERSION = '0.17';
45              
46             @ISA = 'Exporter';
47             @EXPORT = qw|
48             all_files_no_breakpoints_ok
49             all_files_no_brkpts_ok
50             no_breakpoints_ok
51             no_brkpts_ok
52             |;
53             @EXPORT_OK = qw|all_perl_files|;
54             %EXPORT_TAGS = (
55             all => [ @EXPORT, @EXPORT_OK ],
56             );
57              
58             # get a Test singleton to use
59             my $Test = Test::Builder->new;
60              
61             # a regular expression to find soft breakpoints
62             my $brkpt_rx = qr/
63             ( # match it
64             \$DB # The DB package
65             (?:::|') # Perl 4 or 5 package seperator
66             si(?:ngle|gnal) # signal or single
67             \s*=\s* # an equal with optional whitespace
68             [1-9] # a digit other than zero
69             # (am I being stupid here? Is there
70             ) # no easier way to say that?)
71             /x;
72              
73             # check that there are no breakpoints in a file
74             sub no_breakpoints_ok($;$)
75             {
76            
77 21     21 1 16636 my($file, $name) = @_;
78 21   66     88 $name ||= "no breakpoint test of $file";
79            
80             # slurp in the file
81 21         18 my $fh;
82 21 50       627 unless( open($fh, $file) ) {
83 0         0 $Test->ok(0, $name);
84 0         0 $Test->diag("could not open $file: $!");
85 0         0 return;
86             }
87 21         55 my $text = do { local( $/ ) ; <$fh> } ;
  21         62  
  21         563  
88 21         170 close($fh);
89            
90             # check the file against our regex
91 21         150 my($matched) = $text =~ m/$brkpt_rx/;
92 21 100       46 if( ! $matched ) {
93 11         70 $Test->ok(1, $name);
94             }
95             else {
96 10         71 $Test->ok(0, $name);
97 10         3148 $Test->diag("breakpoint found in $file: $matched");
98             }
99            
100 21 100       4902 return $matched ? 0 : 1;
101            
102             }
103              
104             # find all perl files in a given directory
105             # graciously borrwed from Test::Pod::all_pod_files by
106             # Andy Lester / brian d foy
107             sub all_perl_files
108             {
109              
110 2 50   2 1 230 my @queue = @_ ? @_ : _starting_points();
111 2         4 my @files = ();
112              
113 2         6 while ( @queue ) {
114 48         73 my $file = shift @queue;
115 48 100       468 if ( -d $file ) {
116 8         23 local *DH;
117 8 50       187 opendir DH, $file or next;
118 8         178 my @newfiles = readdir DH;
119 8         93 closedir DH;
120              
121 8         114 @newfiles = File::Spec->no_upwards( @newfiles );
122 8 50       12 @newfiles = grep { $_ ne "CVS" && $_ ne ".svn" } @newfiles;
  46         115  
123              
124 8         56 push @queue, map "$file/$_", @newfiles;
125             }
126 48 100       460 if ( -f $file ) {
127 40 100       83 push @files, $file if _is_perl( $file );
128             }
129             } # while
130              
131 2         18 return @files;
132              
133             }
134              
135              
136             sub _starting_points {
137 0 0   0   0 return 'blib' if -e 'blib';
138 0         0 return 'lib';
139             }
140              
141             sub _is_perl {
142 40     40   45 my $file = shift;
143              
144 40 50       71 return 1 if $file =~ /\.PL$/;
145 40 100       71 return 1 if $file =~ /\.p(l|m)$/;
146 36 100       109 return 1 if $file =~ /\.t$/;
147              
148 14         23 local *FH;
149 14 50       315 open FH, $file or return;
150 14         164 my $first = ;
151 14         100 close FH;
152              
153 14 50 33     59 return 1 if defined $first && ($first =~ /^#!.*perl/);
154              
155 14         56 return;
156             }
157              
158             # run no_breakpoints_ok on all files in a given directory
159             sub all_files_no_breakpoints_ok
160             {
161              
162 1 50   1 1 4 my @files = @_ ? @_ : all_perl_files();
163              
164 1         2 my $ok = 1; # presume all succeed
165 1         2 for( @files ) {
166 13 100       18 no_breakpoints_ok($_) or $ok = 0;
167             }
168 1         4 return $ok;
169            
170             }
171              
172             # keep require happy
173             1;
174              
175              
176             __END__