File Coverage

blib/lib/Test/MinimumVersion.pm
Criterion Covered Total %
statement 73 90 81.1
branch 10 24 41.6
condition 9 30 30.0
subroutine 15 18 83.3
pod 4 4 100.0
total 111 166 66.8


line stmt bran cond sub pod time code
1 1     1   52106 use 5.006;
  1         4  
  1         42  
2 1     1   6 use strict;
  1         2  
  1         35  
3 1     1   5 use warnings;
  1         2  
  1         61  
4             package Test::MinimumVersion;
5             {
6               $Test::MinimumVersion::VERSION = '0.101081';
7             }
8 1     1   6 use base 'Exporter';
  1         2  
  1         116  
9             # ABSTRACT: does your code require newer perl than you think?
10              
11              
12 1     1   3564 use CPAN::Meta;
  1         71501  
  1         153  
13 1     1   1344 use File::Find::Rule;
  1         20301  
  1         11  
14 1     1   1166 use File::Find::Rule::Perl;
  1         13309  
  1         15  
15 1     1   1137 use Perl::MinimumVersion 1.32; # numerous bugfies
  1         364399  
  1         97  
16 1     1   17 use version 0.70;
  1         20  
  1         9  
17              
18 1     1   86 use Test::Builder;
  1         3  
  1         948  
19             @Test::MinimumVersion::EXPORT = qw(
20             minimum_version_ok
21             all_minimum_version_ok
22             all_minimum_version_from_metayml_ok
23             all_minimum_version_from_metajson_ok
24             );
25              
26             sub import {
27 1     1   10   my($self) = shift;
28 1         3   my $pack = caller;
29              
30 1         7   my $Test = Test::Builder->new;
31              
32 1         15   $Test->exported_to($pack);
33 1         50   $Test->plan(@_);
34              
35 1         206823   $self->export_to_level(1, $self, @Test::MinimumVersion::EXPORT);
36             }
37              
38             sub _objectify_version {
39 4     4   8   my ($version) = @_;
40 4 100       8   $version = eval { $version->isa('version') }
  4         83  
41                        ? $version
42                        : version->new($version);
43             }
44              
45              
46             sub minimum_version_ok {
47 3     3 1 1353   my ($file, $version) = @_;
48              
49 3         32   my $Test = Test::Builder->new;
50              
51 3         21   $version = _objectify_version($version);
52              
53 3         33   my $pmv = Perl::MinimumVersion->new($file);
54              
55 3 50       12605   unless (defined $pmv) {
56 0         0     $Test->ok(0, $file);
57 0         0     $Test->diag(
58                   "$file could not be parsed: " . PPI::Document->errstr
59                 );
60 0         0     return;
61               }
62              
63 3   50     18   my $explicit_minimum = $pmv->minimum_explicit_version || 0;
64 3   50     1423   my $minimum = $pmv->minimum_syntax_version($explicit_minimum) || 0;
65              
66 3 50 33     46029   my $is_syntax = 1
67                 if $minimum and $minimum > $explicit_minimum;
68              
69 3 50 33     27   $minimum = $explicit_minimum
70                 if $explicit_minimum and $explicit_minimum > $minimum;
71              
72 3         18   my %min = $pmv->version_markers;
73              
74 3 50       67469   if ($minimum <= $version) {
75 3         51     $Test->ok(1, $file);
76               } else {
77 0         0     $Test->ok(0, $file);
78 0 0       0     $Test->diag(
79                   "$file requires $minimum "
80                   . ($is_syntax ? 'due to syntax' : 'due to explicit requirement')
81                 );
82              
83 0 0 0     0     if ($is_syntax and my $markers = $min{ $minimum }) {
84 0         0       $Test->diag("version markers for $minimum:");
85 0         0       $Test->diag("- $_ ") for @$markers;
86                 }
87               }
88             }
89              
90              
91             sub all_minimum_version_ok {
92 1     1 1 2872   my ($version, $arg) = @_;
93 1   50     6   $arg ||= {};
94 1   50     233   $arg->{paths} ||= [
95                 qw(bin script lib t xt/smoke),
96                 glob("*.pm"),
97                 glob("*.PL"),
98               ];
99              
100 1   50     6   $arg->{skip} ||= [];
101              
102 1         7   my $Test = Test::Builder->new;
103              
104 1         9   $version = _objectify_version($version);
105              
106 1         3   my @perl_files;
107 1         2   for my $path (@{ $arg->{paths} }) {
  1         4  
108 5 50 33     2617     if (-f $path and -s $path) {
    100          
109 0         0       push @perl_files, $path;
110                 } elsif (-d $path) {
111 1         15       push @perl_files, File::Find::Rule->perl_file->in($path);
112                 }
113               }
114              
115 1         4   my %skip = map {; $_ => 1 } @{ $arg->{skip} };
  1         8  
  1         5  
116 1         3   @perl_files = grep {; ! $skip{$_} } @perl_files;
  2         9  
117              
118 1 50 33     17   unless ($Test->has_plan or $arg->{no_plan}) {
119 1         47     $Test->plan(tests => scalar @perl_files);
120               }
121              
122 1         437   minimum_version_ok($_, $version) for @perl_files;
123             }
124              
125              
126             sub __version_from_meta {
127 2     2   6662   my ($fn) = @_;
128              
129 2         23   my $meta = CPAN::Meta->load_file($fn, { lazy_validation => 1 })->as_struct;
130 2         78914   my $version = $meta->{prereqs}{runtime}{requires}{perl};
131             }
132              
133             sub __from_meta {
134 0     0       my ($fn, $arg) = @_;
135 0   0         $arg ||= {};
136              
137 0             my $Test = Test::Builder->new;
138              
139 0 0 0         $Test->plan(skip_all => "$fn could not be found")
140                 unless -f $fn and -r _;
141              
142 0 0           $Test->plan(skip_all => "no minimum perl version could be determined")
143                 unless my $version = __version_from_meta($fn);
144              
145 0             all_minimum_version_ok($version, $arg);
146             }
147              
148             sub all_minimum_version_from_metayml_ok {
149 0     0 1     __from_meta('META.yml', @_);
150             }
151              
152              
153 0     0 1   sub all_minimum_version_from_metajson_ok { __from_meta('META.json', @_); }
154              
155             1;
156              
157             __END__
158            
159             =pod
160            
161             =encoding UTF-8
162            
163             =head1 NAME
164            
165             Test::MinimumVersion - does your code require newer perl than you think?
166            
167             =head1 VERSION
168            
169             version 0.101081
170            
171             =head1 SYNOPSIS
172            
173             Example F<minimum-perl.t>:
174            
175             #!perl
176             use Test::MinimumVersion;
177             all_minimum_version_ok('5.008');
178            
179             =head1 FUNCTIONS
180            
181             =head2 minimum_version_ok
182            
183             minimum_version_ok($file, $version);
184            
185             This test passes if the given file does not seem to require any version of perl
186             newer than C<$version>, which may be given as a version string or a version
187             object.
188            
189             =head2 all_minimum_version_ok
190            
191             all_minimum_version_ok($version, \%arg);
192            
193             Given either a version string or a L<version> object, this routine produces a
194             test plan (if there is no plan) and tests each relevant file with
195             C<minimum_version_ok>.
196            
197             Relevant files are found by L<File::Find::Rule::Perl>.
198            
199             C<\%arg> is optional. Valid arguments are:
200            
201             paths - in what paths to look for files; defaults to (bin, script, t, lib,
202             xt/smoke, and any .pm or .PL files in the current working
203             directory) if it contains files, they will be checked
204             no_plan - do not plan the tests about to be run
205             skip - files to skip; this can be useful in weird cases like gigantic
206             files, files falsely detected as Perl, or code that uses
207             a source filter; this should be an arrayref of filenames
208            
209             =head2 all_minimum_version_from_metayml_ok
210            
211             all_minimum_version_from_metayml_ok(\%arg);
212            
213             This routine checks F<META.yml> for an entry in F<requires> for F<perl>. If no
214             META.yml file or no perl version is found, all tests are skipped. If a version
215             is found, the test proceeds as if C<all_minimum_version_ok> had been called
216             with that version.
217            
218             =head2 all_minimum_version_from_metajson_ok
219            
220             all_minimum_version_from_metajson_ok(\%arg);
221            
222             This routine checks F<META.json> for an entry in F<requires> for F<perl>. If
223             no META.json file or no perl version is found, all tests are skipped. If a
224             version is found, the test proceeds as if C<all_minimum_version_ok> had been
225             called with that version.
226            
227             =head1 AUTHOR
228            
229             Ricardo Signes
230            
231             =head1 COPYRIGHT AND LICENSE
232            
233             This software is copyright (c) 2007 by Ricardo Signes.
234            
235             This is free software; you can redistribute it and/or modify it under
236             the same terms as the Perl 5 programming language system itself.
237            
238             =cut
239