File Coverage

blib/lib/Test/Some.pm
Criterion Covered Total %
statement 68 69 98.5
branch 28 30 93.3
condition n/a
subroutine 18 18 100.0
pod n/a
total 114 117 97.4


line stmt bran cond sub pod time code
1             package Test::Some;
2             our $AUTHORITY = 'cpan:YANICK';
3             # ABSTRACT: test a subset of tests
4             $Test::Some::VERSION = '0.2.0';
5              
6 8     8   29380 use 5.10.0;
  8         27  
7              
8 8     8   38 use strict;
  8         12  
  8         189  
9 8     8   37 use warnings;
  8         12  
  8         191  
10              
11 8     8   7047 use Test::More;
  8         131903  
  8         66  
12              
13 8     8   9224 use List::MoreUtils qw/ none any /;
  8         103487  
  8         67  
14              
15             our %filters;
16              
17             our $BYPASS = 0;
18              
19             sub import {
20 8     8   78 my $caller = caller;
21 8         26 my(undef,@filters) = @_;
22              
23 8     8   6209 no warnings 'uninitialized';
  8         16  
  8         4818  
24 8 100       44 @filters = split ',', $ENV{TEST_SOME} unless @filters;
25              
26 8         32 _groom_filter($caller,$_) for @filters;
27              
28 8 50   8   41 eval <<"END_EVAL";
  8     8   15  
  8     8   264  
  8     26   38  
  8         15  
  8         2229  
  8         139  
  8         40  
  8         70  
  26         28506  
  8         761  
29             package $caller;
30              
31             # delaying stuff to INIT
32             # because Test::Some can be loaded before Test::More
33             INIT {
34             my \$original_subtest = $caller->can('subtest')
35             or die "no function 'subtest' found in package $caller. Forgot to import Test::More?";
36              
37             no warnings 'redefine';
38             no strict 'refs';
39             *{"${caller}::subtest"} = sub { Test::Some::_subtest( \$original_subtest, \@_ ) };
40             }
41             END_EVAL
42              
43              
44             }
45              
46             sub _groom_filter {
47 32     32   129 my( $caller, $filter, $is_tag, $is_negated ) = @_;
48              
49 32 100       83 if( $filter eq '~' ) {
50 3         8 $BYPASS = 1;
51 3         11 return;
52             }
53              
54 29 100       143 return _groom_filter( $caller, $filter, 1, $is_negated )
55             if $filter =~ s/^://;
56              
57 24 100       65 return _groom_filter( $caller, $filter, $is_tag, 1 )
58             if $filter =~ s/^!//;
59              
60 22 100       144 return _groom_filter( $caller, qr/$filter/, $is_tag, $is_negated )
61             if $filter =~ s#^/##;
62              
63             my $sub = ref $filter eq 'CODE' ? $filter
64             : $is_tag ? sub {
65 13 100   13   36 if ( ref $filter ) {
66 7         18 for my $key ( keys %_ ) {
67 3 50       31 return 1 if $key =~ $filter;
68             }
69 4         23 return 0;
70             }
71              
72 6         23 return $_{$filter};
73             }
74 15 100   30   92 : sub { ref $filter ? /$filter/ : $_ eq $filter };
  30 100       228  
    100          
75              
76 15 100       48 if( $is_negated ) {
77 2         4 my $prev_sub = $sub;
78 2     5   7 $sub = sub { not $prev_sub->() };
  5         14  
79             }
80              
81 15         20 push @{ $filters{$caller} }, $sub;
  15         74  
82             }
83              
84             sub _should_be_skipped {
85 26     26   50 my( $caller, $name, @tags ) = @_;
86              
87 26         41 for my $filter ( eval { @{ $filters{$caller} } } ) {
  26         31  
  26         96  
88 46         86 local $_ = $name;
89 46         101 local %_ = map { $_ => 1 } @tags;
  21         67  
90 46 100       161 return if $filter->();
91             }
92              
93 7         33 return 1;
94             }
95              
96             sub _subtest {
97 26     26   74 my( $orig, $name, $code, @tags ) = @_;
98 26         53 my $caller = caller;
99              
100 26 100       70 if( _should_be_skipped($caller,$name,@tags) ) {
101 7 100       140 return if $BYPASS;
102             $code = sub {
103 4     4   1964 Test::More::plan( skip_all => 'Test::Some skipping' );
104             $orig->($name, sub { } )
105 0         0 }
106 4         19 }
107              
108 23         159 $orig->( $name, $code );
109             }
110              
111             1;
112              
113             __END__