File Coverage

t/00-report-prereqs.t
Criterion Covered Total %
statement n/a
branch n/a
condition n/a
subroutine n/a
pod n/a
total n/a


line stmt bran cond sub pod time code
1             #!perl
2              
3             use strict;
4             use warnings;
5              
6             # This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.026
7              
8             use Test::More tests => 1;
9              
10             use ExtUtils::MakeMaker;
11             use File::Spec;
12              
13             # from $version::LAX
14             my $lax_version_re =
15             qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )?
16             |
17             (?:\.[0-9]+) (?:_[0-9]+)?
18             ) | (?:
19             v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )?
20             |
21             (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)?
22             )
23             )/x;
24              
25             # hide optional CPAN::Meta modules from prereq scanner
26             # and check if they are available
27             my $cpan_meta = "CPAN::Meta";
28             my $cpan_meta_pre = "CPAN::Meta::Prereqs";
29             my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic
30              
31             # Verify requirements?
32             my $DO_VERIFY_PREREQS = 1;
33              
34             sub _max {
35             my $max = shift;
36             $max = ( $_ > $max ) ? $_ : $max for @_;
37             return $max;
38             }
39              
40             sub _merge_prereqs {
41             my ($collector, $prereqs) = @_;
42              
43             # CPAN::Meta::Prereqs object
44             if (ref $collector eq $cpan_meta_pre) {
45             return $collector->with_merged_prereqs(
46             CPAN::Meta::Prereqs->new( $prereqs )
47             );
48             }
49              
50             # Raw hashrefs
51             for my $phase ( keys %$prereqs ) {
52             for my $type ( keys %{ $prereqs->{$phase} } ) {
53             for my $module ( keys %{ $prereqs->{$phase}{$type} } ) {
54             $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module};
55             }
56             }
57             }
58              
59             return $collector;
60             }
61              
62             my @include = qw(
63              
64             );
65              
66             my @exclude = qw(
67              
68             );
69              
70             # Add static prereqs to the included modules list
71             my $static_prereqs = do './t/00-report-prereqs.dd';
72              
73             # Merge all prereqs (either with ::Prereqs or a hashref)
74             my $full_prereqs = _merge_prereqs(
75             ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ),
76             $static_prereqs
77             );
78              
79             # Add dynamic prereqs to the included modules list (if we can)
80             my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
81             my $cpan_meta_error;
82             if ( $source && $HAS_CPAN_META
83             && (my $meta = eval { CPAN::Meta->load_file($source) } )
84             ) {
85             $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs);
86             }
87             else {
88             $cpan_meta_error = $@; # capture error from CPAN::Meta->load_file($source)
89             $source = 'static metadata';
90             }
91              
92             my @full_reports;
93             my @dep_errors;
94             my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs;
95              
96             # Add static includes into a fake section
97             for my $mod (@include) {
98             $req_hash->{other}{modules}{$mod} = 0;
99             }
100              
101             for my $phase ( qw(configure build test runtime develop other) ) {
102             next unless $req_hash->{$phase};
103             next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING});
104              
105             for my $type ( qw(requires recommends suggests conflicts modules) ) {
106             next unless $req_hash->{$phase}{$type};
107              
108             my $title = ucfirst($phase).' '.ucfirst($type);
109             my @reports = [qw/Module Want Have/];
110              
111             for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) {
112             next if $mod eq 'perl';
113             next if grep { $_ eq $mod } @exclude;
114              
115             my $file = $mod;
116             $file =~ s{::}{/}g;
117             $file .= ".pm";
118             my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC;
119              
120             my $want = $req_hash->{$phase}{$type}{$mod};
121             $want = "undef" unless defined $want;
122             $want = "any" if !$want && $want == 0;
123              
124             my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required";
125              
126             if ($prefix) {
127             my $have = MM->parse_version( File::Spec->catfile($prefix, $file) );
128             $have = "undef" unless defined $have;
129             push @reports, [$mod, $want, $have];
130              
131             if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) {
132             if ( $have !~ /\A$lax_version_re\z/ ) {
133             push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)";
134             }
135             elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) {
136             push @dep_errors, "$mod version '$have' is not in required range '$want'";
137             }
138             }
139             }
140             else {
141             push @reports, [$mod, $want, "missing"];
142              
143             if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) {
144             push @dep_errors, "$mod is not installed ($req_string)";
145             }
146             }
147             }
148              
149             if ( @reports ) {
150             push @full_reports, "=== $title ===\n\n";
151              
152             my $ml = _max( map { length $_->[0] } @reports );
153             my $wl = _max( map { length $_->[1] } @reports );
154             my $hl = _max( map { length $_->[2] } @reports );
155              
156             if ($type eq 'modules') {
157             splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl];
158             push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports;
159             }
160             else {
161             splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl];
162             push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports;
163             }
164              
165             push @full_reports, "\n";
166             }
167             }
168             }
169              
170             if ( @full_reports ) {
171             diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports;
172             }
173              
174             if ( $cpan_meta_error || @dep_errors ) {
175             diag "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n";
176             }
177              
178             if ( $cpan_meta_error ) {
179             my ($orig_source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
180             diag "\nCPAN::Meta->load_file('$orig_source') failed with: $cpan_meta_error\n";
181             }
182              
183             if ( @dep_errors ) {
184             diag join("\n",
185             "\nThe following REQUIRED prerequisites were not satisfied:\n",
186             @dep_errors,
187             "\n"
188             );
189             }
190              
191             pass;
192              
193             # vim: ts=4 sts=4 sw=4 et: