File Coverage

blib/lib/Test/EOFNewlines.pm
Criterion Covered Total %
statement 79 97 81.4
branch 27 50 54.0
condition 8 13 61.5
subroutine 17 17 100.0
pod 1 1 100.0
total 132 178 74.1


line stmt bran cond sub pod time code
1             package Test::EOFNewlines;
2              
3 1     1   22260 use strict;
  1         2  
  1         35  
4 1     1   5 use warnings;
  1         2  
  1         26  
5              
6 1     1   22 use 5.010010;
  1         7  
  1         48  
7             our $VERSION = '0.03';
8              
9 1     1   5 use Cwd qw/cwd/;
  1         2  
  1         49  
10 1     1   4 use File::Find;
  1         9  
  1         72  
11 1     1   1022 use File::ReadBackwards;
  1         3267  
  1         27  
12 1     1   6 use File::Spec;
  1         2  
  1         20  
13 1     1   6 use Test::Builder;
  1         1  
  1         82  
14              
15             my $perlstart = qr/^#!.*perl/;
16             my $test = Test::Builder->new;
17             my $updir = File::Spec->updir;
18              
19             sub import {
20 1     1   7 my $self = shift;
21 1         3 my $caller = caller;
22             {
23 1     1   5 no strict 'refs';
  1         2  
  1         1078  
  1         1  
24 1         2 *{ $caller.'::all_perl_files_ok'} = \&all_perl_files_ok;
  1         6  
25             }
26 1         4 $test->exported_to($caller);
27 1         12 $test->plan(@_);
28             }
29              
30              
31              
32             sub all_perl_files_ok {
33 2 100   2 1 10598 my $options = ref $_[0] eq 'HASH' ? shift : ref $_[-1] eq 'HASH' ? pop : {};
    50          
34 2         28 my @files = _all_perl_files(@_);
35              
36 2         9 _make_plan();
37              
38             # no need to check then...
39 2 50 66     26 if(exists $options->{'minimum_newlines'} && $options->{'minimum_newlines'} <= 0) {
40 0         0 return 1;
41             }
42              
43 2         13 foreach my $file (@files) {
44 2         6 _check_perl_file($file, $options);
45             }
46             }
47              
48             sub _check_perl_file {
49 2     2   6 my $file = shift;
50 2         4 my $options = shift;
51              
52 2 100 66     14 if(exists $options->{'minimum_newlines'} && !exists $options->{'maximum_newlines'}) {
53 1         3 $options->{'maximum_newlines'} = $options->{'minimum_newlines'};
54             }
55 2   100     18 $options->{'minimum_newlines'} ||= 1;
56 2   100     12 $options->{'maximum_newlines'} ||= 1;
57              
58 2         15 $file = _module_to_path($file);
59              
60 2 50       25 my $reader = File::ReadBackwards->new($file) or return;
61              
62 2         228 my $linecount = 0;
63              
64             LINE:
65 2         12 while(my $line = $reader->readline) {
66 4 50       426 ++$linecount if $line =~ m{\n$};
67 4 100       19 next LINE if $line =~ m{^\n$};
68 2         5 last LINE;
69             }
70              
71 2 50       12 if($linecount < $options->{'minimum_newlines'}) {
    50          
72 0         0 $test->ok(0, "Enough empty lines (had $linecount, wanted $options->{'minimum_newlines'}) at the end of $file");
73 0         0 return 0;
74             }
75             elsif($linecount > $options->{'maximum_newlines'}) {
76 0         0 $test->ok(0, "Not too many empty lines (had $linecount, wanted $options->{'maximum_newlines'}) at the end of $file ");
77 0         0 return 0;
78             }
79 2         16 $test->ok(1, "Just the right number of empty lines at the end of $file");
80 2         6974 return 1;
81              
82             }
83              
84             sub _all_perl_files {
85 2 50   2   21 my @base_dirs = @_ ? @_ : cwd();
86 2         7 my @found;
87              
88             my $wants = sub {
89 4 50   4   165 return if $File::Find::dir =~ m{ [\\/]? (?:CVS|\.svn) [\\/] }x;
90 4 50       26 return if $File::Find::dir =~ m{ [\\/]? blib [\\/] (?: libdoc | man\d) $ }x;
91 4 50       20 return if $File::Find::dir =~ m{ [\\/]? inc }x;
92 4 50       444 return if $File::Find::name =~ m{ Build $ }xi;
93 4 100       608 return unless -f -r $File::Find::name;
94 2         503 push @found => File::Spec->no_upwards($File::Find::name);
95 2         26 };
96 2         21 my $find_arg = {
97             wanted => $wants,
98             no_chdir => 1,
99             };
100            
101 2         542 find($find_arg, @base_dirs);
102              
103 2 50       5 my @perls = grep { _is_perl($_) || _is_perl($_) } @found;
  2         14  
104              
105 2         117 return @perls;
106              
107             }
108              
109             sub _is_perl {
110 2     2   4 my $file = shift;
111            
112             # module
113 2 100       22 return 1 if $file =~ m{\.pm$}i;
114 1 50       6 return 1 if $file =~ m{::};
115              
116             # script
117 1 50       5 return 1 if $file =~ m{\.pl}i;
118 1 50       3683 return 1 if $file =~ m{\.t$};
119              
120 0 0       0 open my $fh, '<', $file or return;
121 0         0 my $first = <$fh>;
122 0 0 0     0 if(defined $first && $first =~ $perlstart) {
123 0         0 close $fh;
124 0         0 return 1;
125             }
126              
127             # nope
128 0         0 return;
129              
130             }
131              
132             sub _module_to_path {
133 2     2   3 my $file = shift;
134 2 50       36 return $file unless $file =~ m{::};
135 0         0 my @parts = split /::/ => $file;
136 0         0 my $module = File::Spec->catfile(@parts) . '.pm';
137              
138             CANDIDATE:
139 0         0 foreach my $dir (@INC) {
140 0         0 my $candidate = File::Spec->catfile($dir, $module);
141 0 0       0 next CANDIDATE if !-e -f -r $candidate;
142 0         0 return $candidate;
143             }
144 0         0 return $file;
145             }
146              
147              
148              
149              
150              
151             sub _make_plan {
152 2 50   2   33 unless($test->has_plan) {
153             # $test->plan('no_plan');
154             }
155 2         61 $test->expected_tests;
156             }
157              
158             1;
159             __END__