1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
#!perl -w
use warnings;
use strict;
use Test::More;
use Data::Dumper;
use File::Find;
=head1 DESCRIPTION
This test checks whether all tests still pass when the optional test
prerequisites for the test are not present.
This is done by using L<Test::Without::Module> to rerun the test while excluding
the optional prerequisite.
=cut
BEGIN {
eval {
require CPAN::Meta::Prereqs;
require Parse::CPAN::Meta;
require Perl::PrereqScanner::Lite;
require Module::CoreList;
require Test::Without::Module;
require Capture::Tiny;
Capture::Tiny->import('capture');
require Path::Class;
Path::Class->import('dir');
};
if (my $err = $@) {
warn "# $err";
plan skip_all => "Prerequisite needed for testing is missing";
exit 0;
};
};
my @tests;
if( @ARGV ) {
@tests = @ARGV;
} else {
open my $manifest, '<', 'MANIFEST'
or die "Couldn't read MANIFEST: $!";
@tests = grep { -f $_ } grep { m!^(t/.*\.t|scripts/.*\.pl)$! } map { s!\s*$!!; $_ } <$manifest>
}
plan tests => 0+@tests;
my $meta = Parse::CPAN::Meta->load_file('META.json');
# Find what META.* declares
my $explicit_test_prereqs = CPAN::Meta::Prereqs->new( $meta->{prereqs} )->merged_requirements->as_string_hash;
my $minimum_perl = $meta->{prereqs}->{runtime}->{requires}->{perl} || 5.006;
sub distributed_packages {
my @modules;
for( @_ ) {
dir($_)->recurse( callback => sub {
my( $child ) = @_;
if( !$child->is_dir and $child =~ /\.pm$/) {
push @modules, ((scalar $child->slurp()) =~ m/^\s*package\s+(?:#.*?\n\s+)*(\w+(?:::\w+)*)\b/msg);
}
});
};
map { $_ => $_ } @modules;
}
# Find what we distribute:
my %distribution = distributed_packages('blib','t');
my $scanner = Perl::PrereqScanner::Lite->new;
for my $test_file (@tests) {
my $implicit_test_prereqs = $scanner->scan_file($test_file)->as_string_hash;
my %missing = %{ $implicit_test_prereqs };
#warn Dumper \%missing;
for my $p ( keys %missing ) {
# remove core modules
if( Module::CoreList::is_core( $p, undef, $minimum_perl)) {
delete $missing{ $p };
#diag "$p is core for $minimum_perl";
} else {
#diag "$p is not in core for $minimum_perl";
};
};
# remove explicit (test) prerequisites
for my $k (keys %$explicit_test_prereqs) {
delete $missing{ $k };
};
#warn Dumper $explicit_test_prereqs->as_string_hash;
# Remove stuff from our distribution
for my $k (keys %distribution) {
delete $missing{ $k };
};
# If we have no apparent missing prerequisites, we're good
my @missing = sort keys %missing;
# Rerun the test without these modules and see whether it crashes
my @failed;
for my $candidate (@missing) {
diag "Checking that $candidate is not essential";
my @cmd = ($^X, "-MTest::Without::Module=$candidate", "-Mblib", '-w', $test_file);
my $cmd = join " ", @cmd;
my ($stdout, $stderr, $exit) = capture {
system( @cmd );
};
if( $exit != 0 ) {
push @failed, [ $candidate, [@cmd]];
} elsif( $? != 0 ) {
push @failed, [ $candidate, [@cmd]];
};
};
is 0+@failed, 0, $test_file
or diag Dumper \@failed;
};
done_testing;
|