File Coverage

blib/lib/Test/NoXS.pm
Criterion Covered Total %
statement 44 45 97.7
branch 15 20 75.0
condition 1 3 33.3
subroutine 11 11 100.0
pod n/a
total 71 79 89.8


line stmt bran cond sub pod time code
1 3     3   4304 use 5.006;
  3         11  
2 3     3   15 use strict;
  3         5  
  3         61  
3 3     3   13 use warnings;
  3         5  
  3         164  
4              
5             package Test::NoXS;
6             # ABSTRACT: Prevent a module from loading its XS code
7              
8             our $VERSION = '1.04';
9              
10 3     3   8601 use Module::CoreList 3.00;
  3         312974  
  3         45  
11             require DynaLoader;
12             require XSLoader;
13              
14             my @no_xs_modules;
15             my $no_xs_all;
16             my $xs_core_only;
17             my $xs_core_or_dual;
18              
19             our $PERL_CORE_VERSION = sprintf( "%vd", $^V );
20              
21             sub import {
22 3     3   1799 my $class = shift;
23 3 100       9 if ( grep { /:all/ } @_ ) {
  4 100       24  
    50          
24 1         11 $no_xs_all = 1;
25             }
26 3         13 elsif ( grep { /:xs_core_only/ } @_ ) {
27 1         12 $xs_core_only = 1;
28             }
29 2         5 elsif ( grep { /:xs_core_or_dual/ } @_ ) {
30 0         0 $xs_core_or_dual = 1;
31             }
32             else {
33 1         23 push @no_xs_modules, @_;
34             }
35             }
36              
37             sub _assert_module {
38 4     4   9 my $module = shift;
39 4 100       85 die "XS disabled\n" if $no_xs_all;
40 3 100       6 die "XS disabled for $module\n" if grep { $module eq $_ } @no_xs_modules;
  6         35  
41 2 50 33     14 _assert_in_core($module) if $xs_core_or_dual || $xs_core_only;
42 2 50       4 _assert_exact_core_version($module) if $xs_core_only;
43 2         4 return 1;
44             }
45              
46             sub _assert_in_core {
47 2     2   635 my $module = shift;
48             # Uses explicit $PERL_CORE_VERSION instead of default for testing
49 2 50       8 die "XS disabled for non-core modules"
50             unless Module::CoreList::is_core( $module, undef, $PERL_CORE_VERSION );
51 2         8270 return 1;
52             }
53              
54             sub _assert_exact_core_version {
55 2     2   5 my $module = shift;
56             # Uses explicit $PERL_CORE_VERSION instead of default for testing
57 2         7 my $core_module_version = $Module::CoreList::version{$PERL_CORE_VERSION}{$module};
58 2         40 my $module_version = $module->VERSION;
59 2 100       11 if ( $core_module_version ne $module_version ) {
60 1         19 die "$module installed version: $module_version"
61             . " ne $core_module_version ( shipped with perl $PERL_CORE_VERSION )";
62             }
63 1         6 return 1;
64             }
65              
66             # Overload DynaLoader and XSLoader to fake lack of XS for designated modules
67             for my $orig (qw/DynaLoader::bootstrap XSLoader::load/) {
68             local $^W;
69 3     3   3627 no strict 'refs';
  3         9  
  3         136  
70 3     3   18 no warnings 'redefine';
  3         8  
  3         475  
71             my $coderef = *{$orig}{CODE};
72             *{$orig} = sub {
73 4 50   4   15716 my $caller = @_ ? $_[0] : caller;
74 4         21 _assert_module($caller);
75 2         671 goto $coderef;
76             };
77             }
78              
79             1;
80              
81              
82             # vim: ts=4 sts=4 sw=4 et:
83              
84             __END__