File Coverage

blib/lib/Test/NoXS.pm
Criterion Covered Total %
statement 45 46 97.8
branch 14 20 70.0
condition 1 3 33.3
subroutine 11 11 100.0
pod n/a
total 71 80 88.7


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