File: 99-test-prerequisites.t

package info (click to toggle)
libfilter-signatures-perl 0.19-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 236 kB
  • sloc: perl: 1,321; makefile: 2
file content (121 lines) | stat: -rw-r--r-- 3,421 bytes parent folder | download | duplicates (4)
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;