File Coverage

blib/lib/Test/HasVersion.pm
Criterion Covered Total %
statement 64 64 100.0
branch 17 20 85.0
condition n/a
subroutine 14 14 100.0
pod 3 3 100.0
total 98 101 97.0


line stmt bran cond sub pod time code
1              
2             package Test::HasVersion;
3              
4 6     6   124480 use strict;
  6         14  
  6         159  
5 6     6   32 use warnings;
  6         11  
  6         346  
6              
7             our $VERSION = '0.014';
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 6     6   31 use Test::Builder;
  6         14  
  6         139  
74 6     6   8047 use ExtUtils::MakeMaker; # to lay down my hands on MM->parse_version
  6         752832  
  6         1113  
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 5     5   50 my $self = shift;
82 5         13 my $caller = caller;
83              
84 5         13 for my $func (@EXPORTS) {
85 6     6   50 no strict 'refs';
  6         14  
  6         2376  
86 15         34 *{ $caller . "::" . $func } = \&$func;
  15         77  
87             }
88              
89 5         59 $Test->exported_to($caller);
90 5         61 $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 8     8   14 my $pm = shift;
112 8         14 my $v;
113 8         32 eval { $v = MM->parse_version($pm); };
  8         92  
114 8 50       1743 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 9     9 1 3498 my $file = shift;
132 9 100       36 my $name = @_ ? shift : "$file has version";
133              
134 9 100       181 if ( !-f $file ) {
135 1         5 $Test->ok( 0, $name );
136 1         495 $Test->diag("$file does not exist");
137 1         62 return;
138             }
139              
140 8         24 my $v = _pm_version($file);
141 8         22 my $ok = _is_valid_version($v);
142 8         38 $Test->ok( $ok, $name );
143              
144             #$Test->diag("$file $v ") if $ok && $noisy;
145             }
146              
147             sub _is_valid_version {
148 8 50   8   70 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 2     2 1 344 my @pm_files = all_pm_files(@_);
171 2         5 local $Test::Builder::Level = $Test::Builder::Level + 1;
172 2 100       11 $Test->plan( tests => scalar @pm_files ) unless $Test->has_plan;
173 2         176 for (@pm_files) {
174 4         628 pm_version_ok($_);
175             }
176             }
177              
178             #=begin private
179              
180             =item PRIVATE B<_list_pm_files>
181              
182             @pm_files = _list_pm_files(@dirs);
183              
184             Returns all PM files under the given directories.
185              
186             =cut
187              
188             #=end private
189              
190             # from Module::Which::List - eglob("**/*.pm")
191              
192 6     6   37 use File::Find qw(find);
  6         11  
  6         2036  
193              
194             sub _list_pm_files {
195 3     3   9 my @INC = @_;
196 3         4 my @files;
197              
198             my $wanted = sub {
199 17 100   17   643 push @files, $_ if /\.pm$/;
200 3         15 };
201              
202 3         8 for (@INC) {
203 3         7 my $base = $_;
204 3 50       34 if ( -d $base ) {
205 3         262 find( { wanted => $wanted, no_chdir => 1 }, $base );
206             }
207             }
208 3         29 return sort @files;
209             }
210              
211             =item B
212              
213             @files = all_pm_files()
214             @files = all_pm_files(@files_and_dirs);
215              
216             Implements finding the Perl modules according to the
217             semantics of the previous function C.
218              
219             =cut
220              
221             sub all_pm_files {
222 6     6 1 3576 my @args;
223 6 100       20 if (@_) {
224 2         6 @args = @_;
225             }
226             else {
227 4         446 @args = ( grep( -f, glob("*.pm") ), "lib/" );
228             }
229 6         15 my @pm_files;
230 6         15 for (@args) {
231 11 100       151 if (-f) {
    100          
232 6         17 push @pm_files, $_;
233             }
234             elsif (-d) {
235 3         11 push @pm_files, _list_pm_files($_);
236             }
237             else {
238             # not a file or directory: ignore silently
239             }
240             }
241 6         26 return @pm_files;
242              
243             }
244              
245             =back
246              
247             =head1 USAGE
248              
249             Other usage patterns besides the ones given in the synopsis.
250              
251             use Test::More tests => $num_tests;
252             use Test::HasVersion;
253             pm_version_ok($file1);
254             pm_version_ok($file2);
255              
256             Obviously, you can't plan twice.
257              
258             use Test::More;
259             use Test::HasVersion;
260             plan tests => $num_tests;
261             pm_version_ok($file);
262              
263             C comes from C.
264              
265             use Test::More;
266             use Test::HasVersion;
267             plan 'no_plan';
268             pm_version_ok($file);
269              
270             C is ok either.
271              
272             =head1 SEE ALSO
273              
274             Test::Version
275              
276             Please reports bugs via CPAN RT,
277             http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-HasVersion
278              
279             =head1 AUTHOR
280              
281             A. R. Ferreira, Eferreira@cpan.orgE
282              
283             =head1 COPYRIGHT AND LICENSE
284              
285             Copyright (C) 2006, 2016 by Adriano R. Ferreira
286              
287             This library is free software; you can redistribute it and/or modify
288             it under the same terms as Perl itself.
289              
290             =cut
291              
292             1;
293