File Coverage

blib/lib/Test/MinimumVersion.pm
Criterion Covered Total %
statement 72 91 79.1
branch 10 24 41.6
condition 9 30 30.0
subroutine 15 20 75.0
pod 6 6 100.0
total 112 171 65.5


line stmt bran cond sub pod time code
1 1     1   27786 use 5.006;
  1         3  
2 1     1   5 use strict;
  1         1  
  1         31  
3 1     1   6 use warnings;
  1         1  
  1         52  
4             package Test::MinimumVersion;
5             $Test::MinimumVersion::VERSION = '0.101082';
6             # ABSTRACT: does your code require newer perl than you think?
7 1     1   5 use base 'Exporter';
  1         2  
  1         105  
8              
9             #pod =head1 SYNOPSIS
10             #pod
11             #pod Example F<minimum-perl.t>:
12             #pod
13             #pod #!perl
14             #pod use Test::MinimumVersion;
15             #pod all_minimum_version_ok('5.008');
16             #pod
17             #pod =cut
18              
19 1     1   930 use CPAN::Meta;
  1         34164  
  1         31  
20 1     1   1053 use File::Find::Rule;
  1         8477  
  1         7  
21 1     1   842 use File::Find::Rule::Perl;
  1         7805  
  1         8  
22 1     1   959 use Perl::MinimumVersion 1.32; # numerous bugfies
  1         295519  
  1         74  
23 1     1   12 use version 0.70;
  1         16  
  1         8  
24              
25 1     1   81 use Test::Builder;
  1         2  
  1         925  
26             @Test::MinimumVersion::EXPORT = qw(
27             minimum_version_ok
28             all_minimum_version_ok
29             all_minimum_version_from_metayml_ok
30             all_minimum_version_from_metajson_ok
31             all_minimum_version_from_mymetayml_ok
32             all_minimum_version_from_mymetajson_ok
33             );
34              
35             sub import {
36 1     1   9 my($self) = shift;
37 1         2 my $pack = caller;
38              
39 1         7 my $Test = Test::Builder->new;
40              
41 1         14 $Test->exported_to($pack);
42 1         45 $Test->plan(@_);
43              
44 1         150832 $self->export_to_level(1, $self, @Test::MinimumVersion::EXPORT);
45             }
46              
47             sub _objectify_version {
48 4     4   9 my ($version) = @_;
49 4 100       6 $version = eval { $version->isa('version') }
  4         59  
50             ? $version
51             : version->new($version);
52             }
53              
54             #pod =func minimum_version_ok
55             #pod
56             #pod minimum_version_ok($file, $version);
57             #pod
58             #pod This test passes if the given file does not seem to require any version of perl
59             #pod newer than C<$version>, which may be given as a version string or a version
60             #pod object.
61             #pod
62             #pod =cut
63              
64             sub minimum_version_ok {
65 3     3 1 699 my ($file, $version) = @_;
66              
67 3         21 my $Test = Test::Builder->new;
68              
69 3         17 $version = _objectify_version($version);
70              
71 3         28 my $pmv = Perl::MinimumVersion->new($file);
72              
73 3 50       9263 unless (defined $pmv) {
74 0         0 $Test->ok(0, $file);
75 0         0 $Test->diag(
76             "$file could not be parsed: " . PPI::Document->errstr
77             );
78 0         0 return;
79             }
80              
81 3   50     14 my $explicit_minimum = $pmv->minimum_explicit_version || 0;
82 3   50     1099 my $minimum = $pmv->minimum_syntax_version($explicit_minimum) || 0;
83              
84 3 50 33     35598 my $is_syntax = 1
85             if $minimum and $minimum > $explicit_minimum;
86              
87 3 50 33     18 $minimum = $explicit_minimum
88             if $explicit_minimum and $explicit_minimum > $minimum;
89              
90 3         15 my %min = $pmv->version_markers;
91              
92 3 50       42717 if ($minimum <= $version) {
93 3         35 $Test->ok(1, $file);
94             } else {
95 0         0 $Test->ok(0, $file);
96 0 0       0 $Test->diag(
97             "$file requires $minimum "
98             . ($is_syntax ? 'due to syntax' : 'due to explicit requirement')
99             );
100              
101 0 0 0     0 if ($is_syntax and my $markers = $min{ $minimum }) {
102 0         0 $Test->diag("version markers for $minimum:");
103 0         0 $Test->diag("- $_ ") for @$markers;
104             }
105             }
106             }
107              
108             #pod =func all_minimum_version_ok
109             #pod
110             #pod all_minimum_version_ok($version, \%arg);
111             #pod
112             #pod Given either a version string or a L<version> object, this routine produces a
113             #pod test plan (if there is no plan) and tests each relevant file with
114             #pod C<minimum_version_ok>.
115             #pod
116             #pod Relevant files are found by L<File::Find::Rule::Perl>.
117             #pod
118             #pod C<\%arg> is optional. Valid arguments are:
119             #pod
120             #pod paths - in what paths to look for files; defaults to (bin, script, t, lib,
121             #pod xt/smoke, and any .pm or .PL files in the current working
122             #pod directory) if it contains files, they will be checked
123             #pod no_plan - do not plan the tests about to be run
124             #pod skip - files to skip; this can be useful in weird cases like gigantic
125             #pod files, files falsely detected as Perl, or code that uses
126             #pod a source filter; this should be an arrayref of filenames
127             #pod
128             #pod =cut
129              
130             sub all_minimum_version_ok {
131 1     1 1 1511 my ($version, $arg) = @_;
132 1   50     24 $arg ||= {};
133             $arg->{paths} ||= [
134 1   50     153 qw(bin script lib t xt/smoke),
135             glob("*.pm"),
136             glob("*.PL"),
137             ];
138              
139 1   50     5 $arg->{skip} ||= [];
140              
141 1         5 my $Test = Test::Builder->new;
142              
143 1         8 $version = _objectify_version($version);
144              
145 1         3 my @perl_files;
146 1         2 for my $path (@{ $arg->{paths} }) {
  1         4  
147 5 50 33     1974 if (-f $path and -s $path) {
    100          
148 0         0 push @perl_files, $path;
149             } elsif (-d $path) {
150 1         12 push @perl_files, File::Find::Rule->perl_file->in($path);
151             }
152             }
153              
154 1         3 my %skip = map {; $_ => 1 } @{ $arg->{skip} };
  1         5  
  1         3  
155 1         3 @perl_files = grep {; ! $skip{$_} } @perl_files;
  2         8  
156              
157 1 50 33     10 unless ($Test->has_plan or $arg->{no_plan}) {
158 1         33 $Test->plan(tests => scalar @perl_files);
159             }
160              
161 1         110 minimum_version_ok($_, $version) for @perl_files;
162             }
163              
164             #pod =func all_minimum_version_from_metayml_ok
165             #pod
166             #pod all_minimum_version_from_metayml_ok(\%arg);
167             #pod
168             #pod This routine checks F<META.yml> for an entry in F<requires> for F<perl>. If no
169             #pod META.yml file or no perl version is found, all tests are skipped. If a version
170             #pod is found, the test proceeds as if C<all_minimum_version_ok> had been called
171             #pod with that version.
172             #pod
173             #pod =cut
174              
175             sub __version_from_meta {
176 2     2   3779 my ($fn) = @_;
177              
178 2         20 my $meta = CPAN::Meta->load_file($fn, { lazy_validation => 1 })->as_struct;
179 2         73204 my $version = $meta->{prereqs}{runtime}{requires}{perl};
180             }
181              
182             sub __from_meta {
183 0     0     my ($fn, $arg) = @_;
184 0   0       $arg ||= {};
185              
186 0           my $Test = Test::Builder->new;
187              
188 0 0 0       $Test->plan(skip_all => "$fn could not be found")
189             unless -f $fn and -r _;
190              
191 0 0         $Test->plan(skip_all => "no minimum perl version could be determined")
192             unless my $version = __version_from_meta($fn);
193              
194 0           all_minimum_version_ok($version, $arg);
195             }
196              
197             sub all_minimum_version_from_metayml_ok {
198 0     0 1   __from_meta('META.yml', @_);
199             }
200              
201             #pod =func all_minimum_version_from_metajson_ok
202             #pod
203             #pod all_minimum_version_from_metajson_ok(\%arg);
204             #pod
205             #pod This routine checks F<META.json> for an entry in F<requires> for F<perl>. If
206             #pod no META.json file or no perl version is found, all tests are skipped. If a
207             #pod version is found, the test proceeds as if C<all_minimum_version_ok> had been
208             #pod called with that version.
209             #pod
210             #pod =cut
211              
212 0     0 1   sub all_minimum_version_from_metajson_ok { __from_meta('META.json', @_); }
213              
214             #pod =func all_minimum_version_from_mymetayml_ok
215             #pod
216             #pod all_minimum_version_from_mymetayml_ok(\%arg);
217             #pod
218             #pod This routine checks F<MYMETA.yml> for an entry in F<requires> for F<perl>. If
219             #pod no MYMETA.yml file or no perl version is found, all tests are skipped. If a
220             #pod version is found, the test proceeds as if C<all_minimum_version_ok> had been
221             #pod called with that version.
222             #pod
223             #pod =cut
224              
225 0     0 1   sub all_minimum_version_from_mymetayml_ok { __from_meta('MYMETA.yml', @_); }
226              
227             #pod =func all_minimum_version_from_mymetajson_ok
228             #pod
229             #pod all_minimum_version_from_mymetajson_ok(\%arg);
230             #pod
231             #pod This routine checks F<MYMETA.json> for an entry in F<requires> for F<perl>. If
232             #pod no MYMETA.json file or no perl version is found, all tests are skipped. If a
233             #pod version is found, the test proceeds as if C<all_minimum_version_ok> had been
234             #pod called with that version.
235             #pod
236             #pod =cut
237              
238 0     0 1   sub all_minimum_version_from_mymetajson_ok { __from_meta('MYMETA.json', @_); }
239              
240             1;
241              
242             __END__
243              
244             =pod
245              
246             =encoding UTF-8
247              
248             =head1 NAME
249              
250             Test::MinimumVersion - does your code require newer perl than you think?
251              
252             =head1 VERSION
253              
254             version 0.101082
255              
256             =head1 SYNOPSIS
257              
258             Example F<minimum-perl.t>:
259              
260             #!perl
261             use Test::MinimumVersion;
262             all_minimum_version_ok('5.008');
263              
264             =head1 FUNCTIONS
265              
266             =head2 minimum_version_ok
267              
268             minimum_version_ok($file, $version);
269              
270             This test passes if the given file does not seem to require any version of perl
271             newer than C<$version>, which may be given as a version string or a version
272             object.
273              
274             =head2 all_minimum_version_ok
275              
276             all_minimum_version_ok($version, \%arg);
277              
278             Given either a version string or a L<version> object, this routine produces a
279             test plan (if there is no plan) and tests each relevant file with
280             C<minimum_version_ok>.
281              
282             Relevant files are found by L<File::Find::Rule::Perl>.
283              
284             C<\%arg> is optional. Valid arguments are:
285              
286             paths - in what paths to look for files; defaults to (bin, script, t, lib,
287             xt/smoke, and any .pm or .PL files in the current working
288             directory) if it contains files, they will be checked
289             no_plan - do not plan the tests about to be run
290             skip - files to skip; this can be useful in weird cases like gigantic
291             files, files falsely detected as Perl, or code that uses
292             a source filter; this should be an arrayref of filenames
293              
294             =head2 all_minimum_version_from_metayml_ok
295              
296             all_minimum_version_from_metayml_ok(\%arg);
297              
298             This routine checks F<META.yml> for an entry in F<requires> for F<perl>. If no
299             META.yml file or no perl version is found, all tests are skipped. If a version
300             is found, the test proceeds as if C<all_minimum_version_ok> had been called
301             with that version.
302              
303             =head2 all_minimum_version_from_metajson_ok
304              
305             all_minimum_version_from_metajson_ok(\%arg);
306              
307             This routine checks F<META.json> for an entry in F<requires> for F<perl>. If
308             no META.json file or no perl version is found, all tests are skipped. If a
309             version is found, the test proceeds as if C<all_minimum_version_ok> had been
310             called with that version.
311              
312             =head2 all_minimum_version_from_mymetayml_ok
313              
314             all_minimum_version_from_mymetayml_ok(\%arg);
315              
316             This routine checks F<MYMETA.yml> for an entry in F<requires> for F<perl>. If
317             no MYMETA.yml file or no perl version is found, all tests are skipped. If a
318             version is found, the test proceeds as if C<all_minimum_version_ok> had been
319             called with that version.
320              
321             =head2 all_minimum_version_from_mymetajson_ok
322              
323             all_minimum_version_from_mymetajson_ok(\%arg);
324              
325             This routine checks F<MYMETA.json> for an entry in F<requires> for F<perl>. If
326             no MYMETA.json file or no perl version is found, all tests are skipped. If a
327             version is found, the test proceeds as if C<all_minimum_version_ok> had been
328             called with that version.
329              
330             =head1 AUTHOR
331              
332             Ricardo Signes
333              
334             =head1 CONTRIBUTORS
335              
336             =for stopwords Ricardo SIGNES Steve Hay
337              
338             =over 4
339              
340             =item *
341              
342             Ricardo SIGNES <rjbs@codesimply.com>
343              
344             =item *
345              
346             Ricardo SIGNES <rjbs@cpan.org>
347              
348             =item *
349              
350             Steve Hay <steve.m.hay@googlemail.com>
351              
352             =back
353              
354             =head1 COPYRIGHT AND LICENSE
355              
356             This software is copyright (c) 2007 by Ricardo Signes.
357              
358             This is free software; you can redistribute it and/or modify it under
359             the same terms as the Perl 5 programming language system itself.
360              
361             =cut