File Coverage

blib/lib/Test/HasVersion.pm
Criterion Covered Total %
statement 63 63 100.0
branch 16 20 80.0
condition n/a
subroutine 14 14 100.0
pod 3 3 100.0
total 96 100 96.0


line stmt bran cond sub pod time code
1              
2             package Test::HasVersion;
3              
4 5     5   67991 use strict;
  5         9  
  5         125  
5 5     5   25 use warnings;
  5         10  
  5         266  
6              
7             our $VERSION = '0.013';
8              
9             =head1 NAME
10              
11             Test::HasVersion - Check Perl modules have version numbers
12              
13             =head1 SYNOPSIS
14              
15             C lets you check a Perl module has a version
16             number in a C fashion.
17              
18             use Test::HasVersion tests => 1;
19             pm_version_ok("M.pm", "Valid version");
20              
21             Module authors can include the following in a F
22             file and let C find and check all
23             installable PM files in a distribution.
24              
25             use Test::More;
26             eval "use Test::HasVersion";
27             plan skip_all =>
28             'Test::HasVersion required for testing for version numbers' if $@;
29             all_pm_version_ok();
30              
31             =head1 DESCRIPTION
32              
33             Do you wanna check that every one of your Perl modules in
34             a distribution has a version number? You wanna make sure
35             you don't forget the brand new modules you just added?
36             Well, that's the module you have been looking for.
37             Use it!
38              
39             Do you wanna check someone else's distribution
40             to make sure the author have not committed the sin of
41             leaving Perl modules without a version that can be used
42             to tell if you have this or that feature? C
43             is also for you, nasty little fellow.
44              
45             There's a script F which is installed with
46             this distribution. You may invoke it from within the
47             root directory of a distribution you just unpacked,
48             and it will check every F<.pm> file in the directory
49             and under F (if any).
50              
51             $ test_version
52              
53             You may also provide directories and files as arguments.
54              
55             $ test_version *.pm lib/ inc/
56             $ test_version .
57              
58             (Be warned that many Perl modules in a F directory
59             do not receive versions because they are not used
60             outside the distribution.)
61              
62             Ok. That's not a very useful module by now.
63             But it will be. Wait for the upcoming releases.
64              
65             =head2 FUNCTIONS
66              
67             =over 4
68              
69             =cut
70              
71             # most of the following code was borrowed from Test::Pod
72              
73 5     5   24 use Test::Builder;
  5         11  
  5         110  
74 5     5   6371 use ExtUtils::MakeMaker; # to lay down my hands on MM->parse_version
  5         567396  
  5         851  
75              
76             my $Test = Test::Builder->new;
77              
78             our @EXPORTS = qw( pm_version_ok all_pm_version_ok all_pm_files );
79              
80             sub import {
81 4     4   42 my $self = shift;
82 4         10 my $caller = caller;
83              
84 4         11 for my $func (@EXPORTS) {
85 5     5   41 no strict 'refs';
  5         9  
  5         1808  
86 12         23 *{ $caller . "::" . $func } = \&$func;
  12         56  
87             }
88              
89 4         44 $Test->exported_to($caller);
90 4         49 $Test->plan(@_);
91             }
92              
93             # from Module::Which
94              
95             #=begin private
96              
97             =item PRIVATE B<_pm_version>
98              
99             $v = _pm_version($pm);
100              
101             Parses a PM file and return what it thinks is $VERSION
102             in this file. (Actually implemented with
103             C<< use ExtUtils::MakeMaker; MM->parse_version($file) >>.)
104             C<$pm> is the filename (eg., F).
105              
106             =cut
107              
108             #=end private
109              
110             sub _pm_version {
111 5     5   9 my $pm = shift;
112 5         10 my $v;
113 5         9 eval { $v = MM->parse_version($pm); };
  5         56  
114 5 50       1150 return $@ ? undef : $v;
115             }
116              
117             =item B
118              
119             pm_version_ok('Module.pm');
120             pm_version_ok('M.pm', 'Has valid version');
121              
122             Checks to see if the given file has a valid
123             version. Actually a valid version number is
124             defined and not equal to C<'undef'> (the string)
125             which is return by C<_pm_version> if a version
126             cannot be determined.
127              
128             =cut
129              
130             sub pm_version_ok {
131 6     6 1 3396 my $file = shift;
132 6 100       23 my $name = @_ ? shift : "$file has version";
133              
134 6 100       128 if ( !-f $file ) {
135 1         6 $Test->ok( 0, $name );
136 1         492 $Test->diag("$file does not exist");
137 1         66 return;
138             }
139              
140 5         15 my $v = _pm_version($file);
141 5         15 my $ok = _is_valid_version($v);
142 5         24 $Test->ok( $ok, $name );
143              
144             #$Test->diag("$file $v ") if $ok && $noisy;
145             }
146              
147             sub _is_valid_version {
148 5 50   5   47 defined $_[0] && $_[0] ne 'undef';
149             }
150              
151             =item B
152              
153             all_pm_version_ok();
154             all_pm_version_ok(@PM_FILES);
155              
156             Checks every given file and F<.pm> files found
157             under given directories to see if they provide
158             valid version numbers. If no argument is given,
159             it defaults to check every file F<*.pm> in
160             the current directory and recurses under the
161             F directory (if it exists).
162              
163             If no test plan was setted, C will set one
164             after computing the number of files to be tested. Otherwise,
165             the plan is left untouched.
166              
167             =cut
168              
169             sub all_pm_version_ok {
170 1     1 1 21 my @pm_files = all_pm_files(@_);
171 1 50       6 $Test->plan( tests => scalar @pm_files ) unless $Test->has_plan;
172 1         148 for (@pm_files) {
173 1         3 pm_version_ok($_);
174             }
175             }
176              
177             #=begin private
178              
179             =item PRIVATE B<_list_pm_files>
180              
181             @pm_files = _list_pm_files(@dirs);
182              
183             Returns all PM files under the given directories.
184              
185             =cut
186              
187             #=end private
188              
189             # from Module::Which::List - eglob("**/*.pm")
190              
191 5     5   27 use File::Find qw(find);
  5         11  
  5         1538  
192              
193             sub _list_pm_files {
194 2     2   4 my @INC = @_;
195 2         3 my @files;
196              
197             my $wanted = sub {
198 13 100   13   435 push @files, $_ if /\.pm$/;
199 2         8 };
200              
201 2         4 for (@INC) {
202 2         3 my $base = $_;
203 2 50       21 if ( -d $base ) {
204 2         150 find( { wanted => $wanted, no_chdir => 1 }, $base );
205             }
206             }
207 2         17 return sort @files;
208             }
209              
210             =item B
211              
212             @files = all_pm_files()
213             @files = all_pm_files(@files_and_dirs);
214              
215             Implements finding the Perl modules according to the
216             semantics of the previous function C.
217              
218             =cut
219              
220             sub all_pm_files {
221 5     5 1 3503 my @args;
222 5 100       16 if (@_) {
223 2         7 @args = @_;
224             }
225             else {
226 3         349 @args = ( grep( -f, glob("*.pm") ), "lib/" );
227             }
228 5         8 my @pm_files;
229 5         12 for (@args) {
230 9 100       111 if (-f) {
    100          
231 5         14 push @pm_files, $_;
232             }
233             elsif (-d) {
234 2         6 push @pm_files, _list_pm_files($_);
235             }
236             else {
237             # not a file or directory: ignore silently
238             }
239             }
240 5         20 return @pm_files;
241              
242             }
243              
244             =back
245              
246             =head1 USAGE
247              
248             Other usage patterns besides the ones given in the synopsis.
249              
250             use Test::More tests => $num_tests;
251             use Test::HasVersion;
252             pm_version_ok($file1);
253             pm_version_ok($file2);
254              
255             Obviously, you can't plan twice.
256              
257             use Test::More;
258             use Test::HasVersion;
259             plan tests => $num_tests;
260             pm_version_ok($file);
261              
262             C comes from C.
263              
264             use Test::More;
265             use Test::HasVersion;
266             plan 'no_plan';
267             pm_version_ok($file);
268              
269             C is ok either.
270              
271             =head1 SEE ALSO
272              
273             Test::Version
274              
275             Please reports bugs via CPAN RT,
276             http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-HasVersion
277              
278             =head1 AUTHOR
279              
280             A. R. Ferreira, Eferreira@cpan.orgE
281              
282             =head1 COPYRIGHT AND LICENSE
283              
284             Copyright (C) 2006, 2016 by A. R. Ferreira
285              
286             This library is free software; you can redistribute it and/or modify
287             it under the same terms as Perl itself.
288              
289             =cut
290              
291             1;
292